Compare commits

...

200 Commits

Author SHA1 Message Date
Philip Howard f3b53b6b5f
Merge pull request #939 from coadkins/coadkins-patch-1
Add PNG File subsection to Pico Graphics documentation
2024-05-09 11:02:35 +01:00
coadkins 37c4d22527
Add PNG File subsection to Pico Graphics documentation
I added a subsection for PNG File support in Pico Graphics by copying and adapting the text from these release notes - https://github.com/pimoroni/pimoroni-pico/releases/tag/v1.20.4 - about the PNGdec functionality.
2024-05-08 11:22:07 -04:00
Philip Howard 616b1cc8d6
Merge pull request #938 from pimoroni/ci/py_decl
CI: Add py_decl verify step to catch binary overflows.
2024-05-03 12:25:04 +01:00
Phil Howard 45a9925072 CI: Add py_decl verify step to catch binary overflows. 2024-05-03 10:59:35 +01:00
Connor Linfoot 32c10482d9
Add support for 96x48 display to Interstate75 (#867)
* Add DISPLAY_INTERSTATE75_96X48
2024-04-17 13:41:02 +01:00
Philip Howard 4c44b77193
Merge pull request #912 from pimoroni/patch-picodisplay-180
PicoDisplay: Fix misalignment on rotated Pico Displays (fixes #562.)
2024-04-17 12:54:18 +01:00
Phil Howard 5510c82564 PicoDisplay: Fix rotation offset for #562.
Pico Display would have a pixel offset at 90 and 180 degree rotations.

Add a special case offset tweak for these, and demystify the rotate_180 variable.
2024-04-17 12:44:40 +01:00
Philip Howard 3a10b29f54
Merge pull request #920 from pimoroni/patch-inky7-update-timeout
inky73: Add busy wait timeout.
2024-04-17 12:42:53 +01:00
Phil Howard 8cf276b992 inky73: Add busy wait timeout.
Add a timeout to fix Inky 7.3" hanging on batteries.

Basically assumes the update has finished if it takes > 45s, and allows a subsequent attempt
rather than hanging indefinitely.

Raised, texted and fixed by w3stbam: https://github.com/pimoroni/pimoroni-pico/pull/900

Rewritten as mentioned in the PR.
2024-04-17 12:33:24 +01:00
Philip Howard f1ea35fbbf
Merge pull request #911 from pimoroni/patch-unicorn-brightness
G/S/C Unicorn: Fix get_brightness to use correct max value.
2024-04-11 17:45:48 +01:00
Philip Howard c066325ca0
Merge pull request #909 from pimoroni/patch-ltr559-interrupt
LTR559: Add interrupt.py demo from #169.
2024-04-11 17:41:58 +01:00
Philip Howard fd4eb165f8
Merge pull request #930 from pimoroni/patch-misc-ci-fixes
Slightly less frustrating MicroPython builds.
2024-04-11 17:08:44 +01:00
Phil Howard 8fc8a8ee06 CI: Rename tiny2040 to tiny2040_8mb.
It was not super obvious that this build is specific to the 8mb
version of Tiny 2040.
2024-04-11 17:01:21 +01:00
Phil Howard 3bfb548686 CI: Continue other MicroPython builds if one fails.
In almost all cases it's more useful to know if a given build
is likely to succeed rather than have *everything* fail. This
change adjusts the workflow to allow other builds to continue
if one fails.
2024-04-11 17:01:09 +01:00
Philip Howard 9edcdcc126
Merge pull request #919 from pimoroni/patch-pngdec-palette-offset
PNGdec: Add support for palette offsets and greyscale copy mode
2024-04-11 16:32:08 +01:00
Philip Howard e8e550b18b
Merge pull request #929 from pimoroni/patch/wordclock
Fixed arg order bug
2024-04-11 14:57:07 +01:00
thirdr cdb7b4bf2c fixed arg order bug 2024-04-11 14:02:26 +01:00
Philip Howard 4fc3095433
Merge pull request #925 from pimoroni/patch-actions-nodejs
CI: Update actions to fix nodejs deprecation warnings.
2024-04-08 12:58:00 +01:00
Phil Howard 9c5b529754 CI: Update actions to fix nodejs deprecation warnings. 2024-04-08 12:47:14 +01:00
ZodiusInfuser a87d5581aa
Merge pull request #923 from pimoroni/patch/inventor_encoders
Added example for reading speeds from Inventor 2040W's encoders
2024-04-03 14:57:41 +01:00
ZodiusInfuser 44d7875f7e Relocated example and updated readme 2024-04-03 14:37:26 +01:00
ZodiusInfuser a90c31fb3b More explanation of encoder capture 2024-04-03 14:29:17 +01:00
ZodiusInfuser 458b0ac209 Added a speed reading example for inventor 2024-04-03 14:29:01 +01:00
Phil Howard a537672dd4 PNGdec: Don't convert greys if mode=COPY. 2024-03-28 15:35:05 +00:00
Phil Howard d34e692f51 PNGdec: Don't add palette_offset twice. 2024-03-28 15:30:32 +00:00
Phil Howard 27b913124c PNGdec: Add copy support and offset to greyscale. 2024-03-28 15:04:06 +00:00
Phil Howard c7b788cd1d PNGdec: Add palette offset arg.
Allow index colour PNGs to be copied with a palette offset.

EG: a 4bit PNG could be offset 16 times for as many colour variations.
2024-03-28 15:04:02 +00:00
Philip Howard c386b3e9cf
Merge pull request #910 from pimoroni/patch-readme-stubs
README.md: Add link to pimoroni-pico-stubs.
2024-03-28 10:17:02 +00:00
Philip Howard a7a2e2bee0
Merge pull request #918 from pimoroni/patch-pngdec-1bit
PNGdec: Add greyscale support.
2024-03-27 12:59:25 +00:00
Phil Howard 19fa8864cf PNGdec: Add greyscale support.
Add an optional MODE_PEN to draw the PNG in the current pen colour.

Best used with, but not limited to, 1bit PNG images.
2024-03-27 12:49:09 +00:00
Phil Howard 964cf5eedf G/S/C Unicorn: Fix get_brightness to use correct max value.
Add a comment noting that 256 is the correct maximum brightness.
2024-03-11 21:14:43 +00:00
Phil Howard eab1595352 README.md: Add link to pimoroni-pico-stubs. 2024-03-11 15:04:18 +00:00
Phil Howard 5dd76ed31b LTR559: Add interrupt.py demo from #169. 2024-03-11 13:38:07 +00:00
Philip Howard 6eb0f90e53
Merge pull request #904 from pimoroni/ci/micropython-1.22.2
CI: Bump MicroPython to v1.22.2.
2024-03-06 10:29:16 +00:00
Phil Howard b0d53dadb3 Hub75: avoid clobbering shared IRQ handlers.
MicroPython's DMA class uses shared IRQ handlers, which would be
clobbered by Hub75's use of an exclusive handler.

Additionally clean up some dead code (DMA_IRQ_1??), more epxlicitly
clean up the claimed PIOs and programs, and do not use a fixed
DMA channel. This seems to have fixed a bug whereupon Hub75 would
hardlock on the 5th soft reset.
2024-03-05 10:30:48 +00:00
Phil Howard ad518064e9 CI: Bump MicroPython to v1.22.2. 2024-02-27 16:43:47 +00:00
Philip Howard d83107474e
Merge pull request #907 from pimoroni/patch-pngdec-1bit
Fixes for PNGDEC on Badger 2040 / Badger 2040 W
2024-02-27 16:42:12 +00:00
Phil Howard c4f70df1cf Pen1BitY: Correct RGB to dither lookup conversion. 2024-02-27 13:54:25 +00:00
Phil Howard 10221066dd PNGDEC: Support for 1bpp. 2024-02-27 13:31:52 +00:00
Philip Howard ab64fcaccc
Merge pull request #899 from pimoroni/jpegdec/width_height_fix
JPEGDEC: Backport width/height changes from pngdec.
2024-02-27 12:21:17 +00:00
Hel Gibbons 32c63c343d
Merge pull request #905 from pimoroni/helgibbons-patch-3
Plasma Stick: add link
2024-02-26 14:24:49 +00:00
Hel Gibbons 8d964bce2c
Plasma Stick: add link 2024-02-26 14:08:56 +00:00
ZodiusInfuser 8ca47d6405
Merge pull request #890 from robberwick/motor2040_i2c_pins
Add I2C pin definitions to motor2040 and servo2040 headers
2024-02-13 12:00:05 +00:00
Skyler Mansfield b23a71b889 JPEGDEC: Backport width/height changes from pngdec.
Open JPEG file or stream to read width/height before decode.
2024-01-23 16:18:13 +00:00
Philip Howard 6b23c1526d
Merge pull request #898 from pimoroni/patch-tufty2040-567
st7789: Remove mystery meat command implicated by #567.
2024-01-23 15:09:49 +00:00
Phil Howard c19b2276f1 st7789: Remove mystery meat command implicated by #567.
This should, in theory, fix the weird display corruption bug affecting Tufty 2040.
2024-01-23 13:14:12 +00:00
Philip Howard 392d75b00d
Merge pull request #878 from pimoroni/ci/tooling
CI: Move some workflow steps into ci/micropython.sh
2024-01-19 10:32:20 +00:00
Philip Howard 911cbb710e
Merge pull request #877 from pacohope/tz-adjust
add adjustment for time zone offset
2024-01-16 14:35:16 +00:00
Philip Howard 4e3e2c836d
Merge pull request #876 from pimoroni/docs/picoscroll
update picoscroll docs
2024-01-16 14:27:06 +00:00
Philip Howard 5bd5334379
Merge pull request #813 from andrewjw/andrewjw-patch-1
fix: Only set time if the wlan is connected
2024-01-16 14:18:37 +00:00
Philip Howard 9ddbb17a82
Merge pull request #860 from pimoroni/patch-bye-bye-badger
Badger2040/2040W: Remove old/incompatible examples.
2024-01-16 14:17:08 +00:00
Phil Howard 5126263f91 Badger2038/2040W: Remove old/incompatible examples.
Badger now lives at: https://github.com/pimoroni/badger2040
2024-01-16 14:01:34 +00:00
Philip Howard 0d3fce9b9d
Merge pull request #883 from raybellis/main
fix hue errors in plasma_stick_rainbows
2024-01-16 11:32:43 +00:00
Rob Berwick 9e6a0725c0 add `I2C_*` definitions to `servo2040.hpp`
Add pin definitions for `I2C_INT`, `I2C_SDA`, and `I2C_SCL` to `servo2040.hpp`
2024-01-08 13:08:44 +00:00
Rob Berwick 3e81b245a1 add I2C_INT & reorder
Add `I2C_INT` to `motor2040.hpp` and put pin defs in numeric order.
2024-01-08 12:57:30 +00:00
Phil Howard bd6bd289d1 CI: Try to ccache mpy-cross 2024-01-08 11:20:08 +00:00
Phil Howard b6953c25a1 CI: Tidy up build steps 2024-01-08 11:20:08 +00:00
Phil Howard b5df0ac277 CI: Setup version env, patch skipped message. 2024-01-08 11:20:08 +00:00
Phil Howard 116bbb1296 CI: Use arm-none-eabi-gcc-action
Speeds up toolchain install (when cached) to ~7s an decouples us from the runner OS ARM GCC version.
2024-01-08 11:20:08 +00:00
Phil Howard 6154116662 CI: Move build steps to a bash script. 2024-01-08 11:20:04 +00:00
Phil Howard d45daef654 MicroPython: Switch from MICROPY_EVENT_POLL_HOOK to mp_event_handle_nowait().
Note: Unsure if mp_event_handle_nowait() is the right answer in all cases,
but this seems to be what we want in our blocking loops.
2024-01-08 10:33:28 +00:00
Phil Howard 1b3d9d9fb2 Pimoroni I2C: Update to use modmachine.h consolidated header. 2024-01-08 10:15:28 +00:00
Phil Howard 4dd76525f6 CI: Update MicroPython patch for v1.22.1. 2024-01-08 10:06:17 +00:00
Phil Howard 3bac13fcc8 CI: Bump MicroPython to v1.22.1. 2024-01-08 09:46:43 +00:00
Hel Gibbons bff245324b
Merge pull request #886 from bitcdr/feature/add-other-resource-to-plasma-stick-examples-readme
[Plasma Stick 2040W] add Plasma LEDs link
2024-01-03 14:36:04 +00:00
Hel Gibbons 400347b862
Merge pull request #888 from everyplace/main
[Inky Frame] Fix news headline redirect example
2024-01-03 13:03:42 +00:00
Ray Bellis da0ac1821f resolve precision error in python example too 2024-01-02 22:22:09 +00:00
Rob Berwick 6dcc0d4fa0 Add I2C pin definitions to motor2040 header
Add definitions for the QW/ST connector SDA & SCL pins
2024-01-01 20:07:58 +00:00
Erin Sparling fc3f8e5654 Updated commented out url protocols as well 2023-12-29 13:26:33 -05:00
Erin Sparling c001f9bb59 Swapped protocol for https so redirect handling isn't necessary 2023-12-29 13:24:08 -05:00
Erin Sparling 59fa0a1ff8 Added comment for 7.3 frame 2023-12-29 13:23:31 -05:00
Stefan Werder a803c3cee4 add Plasma LEDs link 2023-12-21 00:43:19 +01:00
Ray Bellis 6fd667b1ca fix hue errors in plasma_stick_rainbows 2023-12-13 21:43:01 +00:00
Paco Hope 078d81312f add adjustment for time zone offset 2023-11-14 22:05:12 -05:00
Hel Gibbons a60c856ea8 update picoscroll docs 2023-11-09 12:53:03 +00:00
Philip Howard b4451c3bdc
Merge pull request #862 from pimoroni/patch-polygon-clip
Pico Graphics: Avoid unecessary and broken polygon scanline clip.
2023-10-16 10:46:58 +01:00
Phil Howard ce42d814a7 Pico Graphics: Avoid unecessary and broken polygon scanline clip. 2023-10-16 09:56:40 +01:00
Philip Howard ee7f2758dd
Merge pull request #858 from pimoroni/patch-bump-micropython-oct-2023
CI: Bump MicroPython to v1.21.0.
2023-10-06 17:47:02 +01:00
Phil Howard 388d8af3dc Unicorn/others: Add SDCard library from micropython-lib to RPI_PICO_W builds. 2023-10-06 13:55:29 +01:00
Phil Howard 0f75a2839f Inky Frame: Include SDCard from micropython-lib. 2023-10-06 13:55:29 +01:00
Phil Howard e691628723 CI: Bump MicroPython to v1.21.0.
I swear I had no idea this was imminent.

Changes: 856e08b193...v1.21.0
2023-10-06 13:55:29 +01:00
Phil Howard 08ce4fbb81 MicroPython: Update boards to match upstream naming conventions. 2023-10-06 13:55:29 +01:00
Phil Howard 20de8a3198 CI: Bump MicroPython to 6f76d1c.
Changes: 856e08b193...6f76d1c7fa
2023-10-06 13:55:29 +01:00
Philip Howard 9499b7e908
Merge pull request #855 from pimoroni/patch-jpegdec
JPEGDEC: Treat byte arrays as raw JPEG data for #435.
2023-10-06 13:55:17 +01:00
Philip Howard 65fd3b1c5a
Merge pull request #850 from pimoroni/helgibbons-patch-1
IOExpander: add I2C address change example
2023-09-29 09:38:44 +01:00
Phil Howard 4b3e83f2ff JPEGDEC: Treat byte arrays as raw JPEG data for #435. 2023-09-29 09:18:55 +01:00
Philip Howard fc777ff0ca
Merge pull request #852 from pimoroni/helgibbons-patch-2
Add I2C pins for PicoVision
2023-09-27 10:57:10 +01:00
Hel Gibbons 5345cc42d2
Add I2C pins for PicoVision 2023-09-25 14:53:54 +01:00
Hel Gibbons 169ed9c763 IOExpander: add I2C address change example 2023-09-21 16:16:10 +01:00
Philip Howard 8eac60afc6
Merge pull request #846 from pimoroni/patch-bitmap-fixed-space
Bitmap Fonts: Fixed-width space for #765.
2023-09-15 09:32:23 +01:00
Phil Howard 93525a422f Bitmap Fonts: Fixed-width space for #765. 2023-09-15 09:07:59 +01:00
Hel Gibbons 36f3e3a69f
Merge pull request #844 from pimoroni/helgibbons-patch-1
Galactic: add links
2023-09-14 10:37:35 +01:00
Hel Gibbons 29a13305d2
Update README.md 2023-09-13 10:57:56 +01:00
Philip Howard 1f4704afdb
Merge pull request #843 from pimoroni/feature/picovector
PicoVector - Fixes & Improvements
2023-09-12 13:49:17 +01:00
Phil Howard ae7e6e8c6c PicoVector: Add a bounds method for polygon bounds. 2023-09-12 13:18:33 +01:00
Phil Howard 5f730ff400 PicoVector: Pass PicoGraphics clip into Pretty Poly. 2023-09-12 12:03:09 +01:00
Philip Howard c3919bd648
Merge pull request #840 from MichaelBell/patch-pretty-poly-perf
Improve pretty_poly performance
2023-09-11 12:03:25 +01:00
Philip Howard ed3ce45f00
Merge pull request #842 from MichaelBell/patch-fix-text-newline
Fix newlines in rotated text
2023-09-11 11:37:38 +01:00
Philip Howard 1a7deaab71
Merge pull request #841 from MichaelBell/patch-fix-vector-transform
Initialize all matrix values
2023-09-11 11:36:52 +01:00
Philip Howard 9735402ee3
Merge pull request #839 from MichaelBell/feature/fast-blend
Allow pen function for fast tile alpha blending
2023-09-11 11:36:04 +01:00
Philip Howard c045c405c3
Merge pull request #838 from MichaelBell/patch-micropython-build
Fix clean Micropython build
2023-09-11 10:32:46 +01:00
Mike Bell 80e1e16782 Fixes from compiling with gcc 12 2023-09-10 21:02:16 +01:00
Mike Bell cdd648f3f6 Small improvements to rotated font rendering 2023-09-10 17:20:44 +01:00
Mike Bell 81f42f25b6 Fix newlines in rotated text 2023-09-10 17:20:10 +01:00
Mike Bell 841c141ebf Interpolators for line segment, and faster transforms 2023-09-10 13:22:21 +01:00
Mike Bell c812eec432 Initialize all matrix values 2023-09-10 13:18:13 +01:00
Mike Bell 41eb2b503e Additional improvements to pretty_poly 2023-09-10 00:08:35 +01:00
Mike Bell 581481c2ef Improve pretty_poly performance
(cherry picked from commit 1077a12ff4fd958a7ea6d9e4fa5a86551eba5126)
2023-09-09 01:30:10 +01:00
Mike Bell e908d5e53e Allow pen function for fast tile alpha blending 2023-09-08 23:48:16 +01:00
Mike Bell 34b8ac9f0c Wrap pio.h includes in NO_QSTR so a fresh Micropython build doesn't fall over. 2023-09-08 18:59:25 +01:00
Philip Howard 9124b376d2
Merge pull request #837 from pimoroni/patch-tufty2040-vector
Tufty 2040: Vector examples.
2023-09-07 10:38:26 +01:00
Phil Howard c725b4eee0 Tufty 2040: Vector examples.
Add AdvRe.af for PicoW Explorer and Tufty 2040 spectrometer examples.
2023-09-07 10:14:32 +01:00
Philip Howard a334899b61
Merge pull request #783 from pimoroni/feature/ppaf
PicoVector.
2023-09-06 15:15:30 +01:00
Phil Howard cca2d569e4 PicoVector: Add vector spectrometer example for PicoW Explorer. 2023-09-06 14:07:23 +01:00
Philip Howard 3d8f8c9a83
Merge pull request #829 from ahnlak/lib-driver-include-fixes
Added includes to allow for libraries to be linked to out-of-tree
2023-09-06 10:32:53 +01:00
Phil Howard 788f6c3232 PicoVector: Add clock example for PicoW Explorer. 2023-09-06 10:31:40 +01:00
Phil Howard 231ceb70f2 PicoVector: Add basic polygon center of mass function. 2023-09-06 10:12:08 +01:00
Phil Howard c9fd68ec58 PNGDEC: Remove PNG RAM debug text. 2023-09-06 09:39:28 +01:00
Hel Gibbons b82429caf0
Merge pull request #834 from pimoroni/helgibbons-patch-1
Cosmic Unicorn: add link
2023-09-06 09:39:18 +01:00
Hel Gibbons 386a3594c0
Cosmic Unicorn: add link 2023-09-05 17:31:25 +01:00
Hel Gibbons 9e0b3adc0c
Merge pull request #830 from ahnlak/pico-unicorn-mp-examples
Added some PicoGraphics based MP examples for the PicoUnicorn
2023-09-05 16:46:52 +01:00
Pete Favelle 8c3a21ec1a Made sure all columns are used! 2023-09-05 16:09:02 +01:00
Pete Favelle 2f44e85431 Added some PicoGraphics based MP examples for the PicoUnicorn 2023-09-04 14:31:32 +01:00
Phil Howard 5a92a9c735 PNGDEC: Support for 2bpp indexed PNGs, fix open_RAM. 2023-09-04 13:55:15 +01:00
Pete Favelle 8a9ef39158 Added includes to allow for libraries to be linked to out-of-tree 2023-08-31 10:05:08 +01:00
Phil Howard c443f8d206 PicoVector: Tweak polygon tile rendering loop. 2023-08-22 09:32:28 +01:00
Phil Howard 591058fb12 PicoVector: Store pointer to PP mem. 2023-08-22 09:32:28 +01:00
Phil Howard cfe8b3c096 PicoVector: Text rotation support. 2023-08-22 09:32:28 +01:00
Phil Howard 9d0501a43c PicoVector: Polygon iter interface. 2023-08-22 09:32:28 +01:00
Phil Howard 7c5ebfce8c PicoVector: Matrix transforms and polygon type. 2023-08-22 09:32:28 +01:00
Phil Howard 61c9d7e9b6 PicoVector: Experimental matrix transforms. 2023-08-22 09:32:28 +01:00
Phil Howard c7d9fe411a PicoVector: Bugfixes and font/aa options. 2023-08-22 09:32:28 +01:00
Phil Howard 4671607b3a PicoVector: Vector anti-aliasing support. 2023-08-22 09:32:28 +01:00
Phil Howard 95ab839ba5 PicoVector: Text wrap support. 2023-08-22 09:32:28 +01:00
Phil Howard 9e430fd68c PicoVector: Better separation of concerns, add Alright Fonts support. 2023-08-22 09:32:28 +01:00
Phil Howard c9a8d5ef49 PicoVector: Move polygon drawing to a new home. 2023-08-22 09:32:28 +01:00
Phil Howard 38aaa04c5d Tufty 2040: Basic pretty polygon example. 2023-08-22 09:32:28 +01:00
Phil Howard e8dba75aff PicoGraphics: Use std:: prefix, fix some type issues. 2023-08-22 09:32:28 +01:00
Phil Howard 09a58b269f PicoGraphics: Various compile warning fixes for Pretty Poly. 2023-08-22 09:32:28 +01:00
Phil Howard cc7219b44a PicoGraphics: Experimental Pretty Poly bring-up. 2023-08-22 09:32:28 +01:00
Philip Howard 57042bfed3
Merge pull request #821 from pimoroni/dv_stick_minimal
PicoVision: Minimal changes required to support PV specific drivers/pen types.
2023-08-22 09:31:30 +01:00
Hel Gibbons dc4ee0d459
Merge pull request #822 from pimoroni/helgibbons-patch-1
stellar: correct paths to tiny font
2023-08-21 15:59:14 +01:00
Hel Gibbons 157180c476 stellar: correct path to font 2023-08-21 14:28:08 +01:00
Hel Gibbons 7344e4d1a4
stellar: correct path to 3x5 font 2023-08-21 14:16:25 +01:00
Phil Howard 1157e605a1 Picovision: Remove DV stick drivers to PV repo. 2023-08-21 14:04:49 +01:00
Philip Howard b82d16e8ae
Merge pull request #817 from pimoroni/feature/pico-explorer-pins
PicoGraphics: Add Pico W Explorer SPI pins.
2023-08-15 15:52:51 +01:00
Hel Gibbons 095122c606
Merge pull request #816 from pimoroni/helgibbons-patch-1
Galactic Unicorn: add link
2023-08-14 12:42:36 +01:00
Mike Bell 211e0aa618 DV Display: Fix unaligned read across page boundary 2023-08-14 12:40:15 +01:00
Mike Bell b8116fc371 DV Display: Ability to load sprites in native format 2023-08-14 12:40:15 +01:00
Mike Bell 0cfcb22aa4 DV Display: Add sprite test to cmake 2023-08-14 12:40:15 +01:00
Mike Bell 3cdfe558e8 DV Display: Ability to specify sprite blend mode 2023-08-14 12:40:15 +01:00
Mike Bell 103228a88d DV Display: Sprites in palette mode 2023-08-14 12:40:15 +01:00
Mike Bell 3a5f069ec1 DV Display: Fix clear sprite, fix tearing 2023-08-14 12:40:15 +01:00
Mike Bell 765b8a6226 DV Display: Begin exposing sprites 2023-08-14 12:40:15 +01:00
Mike Bell 3c2c7ccc94 DV Display: Support multiple scroll offsets 2023-08-14 12:40:15 +01:00
Mike Bell b9cd998709 DV Display: Allow scrolling by single pixel in x coordinate 2023-08-14 12:40:15 +01:00
Mike Bell 1a54f7b77d DV Display: Ability to specify a larger frame than the display, and scroll it 2023-08-14 12:40:15 +01:00
Mike Bell 8f78e3d6bc DV Display: Switch SWD loader back to pio0 to avoid conflict with wifi 2023-08-14 12:40:15 +01:00
Mike Bell a396512e7f DV Display: Expose reset functionality 2023-08-14 12:40:15 +01:00
Mike Bell 9a0b21d417 DV Display: Fix palette error 2023-08-14 12:40:15 +01:00
Mike Bell e9779fc0e7 DV Display: Probable fix for frame corruption 2023-08-14 12:40:15 +01:00
Mike Bell 559ce08e04 DV Display: Fix C++ examples 2023-08-14 12:40:15 +01:00
Phil Howard cbc05863c0 DV Display: Claim unused channels and SMs. 2023-08-14 12:40:15 +01:00
Phil Howard 7d8bbf5c08 DV Display: Claim DMA channels and cleanup unused pio_prog.
TODO: Use claim_unused_channel in a way that survives MicroPython soft reset.
2023-08-14 12:40:15 +01:00
Mike Bell 7e9f16d80c DV Display: Pixel doubled palette mode 2023-08-14 12:40:15 +01:00
Mike Bell 4b57162c06 DV Display: External I2C interface option 2023-08-14 12:40:15 +01:00
Phil Howard de4aaa80b6 DV Display: Refactor pio usage with mutex program loader. 2023-08-14 12:40:15 +01:00
Phil Howard 4afe062d19 MicroPython: Make DV display us fixed pio/dma. 2023-08-14 12:40:15 +01:00
Mike Bell 3bc215074c Make it possible to derive from DVDisplay if you want to do fancy things with the frame header 2023-08-14 12:40:15 +01:00
Mike Bell a6bd626334 RGB888 JPEG decode (implemented in some cases only) 2023-08-14 12:40:15 +01:00
Mike Bell 575e806cc8 Remove unnecessary data from JPEG range tables 2023-08-14 12:40:15 +01:00
Mike Bell be943bd5a0 Fix build 2023-08-14 12:40:15 +01:00
Mike Bell daf7232024 Limited support for palette and RGB888 modes 2023-08-14 12:40:15 +01:00
Mike Bell a7435c6a5e GPIO High and palette mode support 2023-08-14 12:40:15 +01:00
Mike Bell 5a6aa0186c Add EDID decoder 2023-08-14 12:40:15 +01:00
Mike Bell 360588ff67 LED control 2023-08-14 12:40:15 +01:00
Mike Bell 4ed1d61336 Ability to read EDID 2023-08-14 12:40:15 +01:00
Mike Bell 31b480d138 Support for half resolutions (pixel/line doubling in the driver) 2023-08-14 12:40:15 +01:00
Mike Bell c7049f4ff1 Ability to choose the resolution for the display 2023-08-14 12:40:15 +01:00
Mike Bell 1d8c836635 Read button state from display driver 2023-08-14 12:40:15 +01:00
Mike Bell e295e69c72 Slideshow from jpegs in SD card directory 2023-08-14 12:40:15 +01:00
Mike Bell 5971bc9ad8 Streamline RAM writes 2023-08-14 12:40:15 +01:00
Mike Bell a1caa9495c Buffer sequential writes 2023-08-14 12:40:15 +01:00
Mike Bell f4b8bc9025 Fix Micropython build 2023-08-14 12:40:15 +01:00
Mike Bell 2e8632f2b6 Use rescue DP to always get driver into a known state before load, boot via watchdog, better logging from driver. 2023-08-14 12:40:15 +01:00
Mike Bell da36b0ad32 Load DV Stick Driver over SWD. Currently unreliable. 2023-08-14 12:40:15 +01:00
Mike Bell 9acc270418 Growing circles - runs at 30FPS 2023-08-14 12:40:15 +01:00
Mike Bell 5f8e7556f0 Begin DV Stick display driver 2023-08-14 12:40:15 +01:00
Philip Howard a7efef0049
Merge pull request #815 from pimoroni/toolchain_env
Fix out of box failure when ARM toolchain is not in path
2023-08-14 12:27:44 +01:00
Hel Gibbons 5a5786d066
Merge pull request #812 from simonprickett/add-gfx-pack-carbon-intensity
Add gfx pack carbon intensity bar graph example.
2023-08-14 11:01:25 +01:00
Simon Prickett 710863099d Another go at the linter. 2023-08-14 10:40:43 +01:00
Simon Prickett 316957c263 Import order changed. 2023-08-12 13:39:18 +01:00
Simon Prickett 9b18ed2594 Further linter checks after running pylint in VSCode. 2023-08-12 13:38:25 +01:00
Simon Prickett 658025a99b Linter issues. 2023-08-12 13:33:03 +01:00
Hel Gibbons fef22530ea
Galactic Unicorn: add link 2023-08-11 16:38:33 +01:00
Angus Logan fc28845fb9 * Fix out of box failure when ARM toolchain is not in path
- Use pico_find_compiler to find linker
2023-08-11 11:48:58 +01:00
Andrew Wilkinson 14c7f6c9c8
fix: Only set time if the wlan is connected
Previously, if we dropped out of the wlan loop early because of an error (wlan.status() < 0) it would still print "Connected", and try to set the time.
2023-08-10 15:58:52 +01:00
Simon Prickett 14eabf360f Adds carbon intensity graph example. 2023-08-07 22:47:01 +01:00
Simon Prickett fe805a711a Adds carbon intensity graph example. 2023-08-07 22:46:55 +01:00
Phil Howard b368950f02 PicoGraphics: Add Pico W Explorer SPI pins. 2023-07-27 17:14:01 +01:00
217 changed files with 3924 additions and 8290 deletions

View File

@ -25,7 +25,7 @@ jobs:
steps:
- name: Compiler Cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: /home/runner/.ccache
key: ccache-cmake-${{github.ref}}-${{matrix.board}}-${{github.sha}}
@ -34,13 +34,13 @@ jobs:
ccache-cmake-${{github.ref}}
ccache-cmake
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
# Check out the Pico SDK
- name: Checkout Pico SDK
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: raspberrypi/pico-sdk
path: pico-sdk
@ -48,7 +48,7 @@ jobs:
# Check out the Pico Extras
- name: Checkout Pico Extras
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: raspberrypi/pico-extras
path: pico-extras

View File

@ -7,72 +7,21 @@ on:
types: [created]
env:
MICROPYTHON_VERSION: 856e08b1931b88271816a2f60648f6ff332235b2
WORKFLOW_VERSION: v1
MICROPYTHON_VERSION: v1.22.2
jobs:
deps:
runs-on: ubuntu-20.04
name: Dependencies
steps:
- name: Workspace Cache
id: cache
uses: actions/cache@v3
with:
path: ${{runner.workspace}}
key: workspace-micropython-${{env.MICROPYTHON_VERSION}}-${{env.WORKFLOW_VERSION}}
restore-keys: |
workspace-micropython-${{env.MICROPYTHON_VERSION}}-${{env.WORKFLOW_VERSION}}
# Check out MicroPython
- name: Checkout MicroPython
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v3
with:
repository: micropython/micropython
ref: ${{env.MICROPYTHON_VERSION}}
submodules: false # MicroPython submodules are hideously broken
path: micropython
# Check out MicroPython Libs
- name: Checkout MicroPython Libs
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v3
with:
repository: micropython/micropython-lib
path: micropython-lib
- name: Fetch Pico submodules
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
working-directory: micropython/ports/rp2
run: |
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
- name: Build mpy-cross
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
working-directory: micropython/mpy-cross
run: make
build:
needs: deps
name: ${{matrix.name}} (${{matrix.board}})
name: ${{ matrix.name }} (${{ matrix.board }})
runs-on: ubuntu-20.04
continue-on-error: true
strategy:
matrix:
include:
- name: pico
board: PICO
board: RPI_PICO
- name: picow
board: PICO_W
- name: tiny2040
board: RPI_PICO_W
- name: tiny2040_8mb
board: PIMORONI_TINY2040
- name: picolipo_4mb
board: PIMORONI_PICOLIPO_4MB
@ -82,102 +31,111 @@ jobs:
board: PIMORONI_TUFTY2040
- name: enviro
board: PICO_W_ENVIRO
patch: true
- name: galactic_unicorn
board: PICO_W
board: RPI_PICO_W
- name: cosmic_unicorn
board: PICO_W
board: RPI_PICO_W
- name: stellar_unicorn
board: PICO_W
board: RPI_PICO_W
- name: inky_frame
board: PICO_W_INKY
patch: true
env:
# MicroPython version will be contained in github.event.release.tag_name for releases
RELEASE_FILE: pimoroni-${{matrix.name}}-${{github.event.release.tag_name || github.sha}}-micropython
MICROPY_BOARD_DIR: "$GITHUB_WORKSPACE/pimoroni-pico-${{ github.sha }}/micropython/board/${{ matrix.BOARD }}"
USER_C_MODULES: "$GITHUB_WORKSPACE/pimoroni-pico-${{ github.sha }}/micropython/modules/micropython-${{matrix.name}}.cmake"
RELEASE_FILE: pimoroni-${{ matrix.name }}-${{ github.event.release.tag_name || github.sha }}-micropython
PIMORONI_PICO_DIR: "${{ github.workspace }}/pimoroni-pico-${{ github.sha }}"
MICROPY_BOARD_DIR: "${{ github.workspace }}/pimoroni-pico-${{ github.sha }}/micropython/board/${{ matrix.BOARD }}"
USER_C_MODULES: "${{ github.workspace }}/pimoroni-pico-${{ github.sha }}/micropython/modules/micropython-${{ matrix.name }}.cmake"
TAG_OR_SHA: ${{ github.event.release.tag_name || github.sha }}
MICROPY_BOARD: ${{ matrix.board }}
BOARD_NAME: ${{ matrix.name }}
BUILD_TOOLS: pimoroni-pico-${{ github.sha }}/ci/micropython.sh
steps:
- name: Compiler Cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: /home/runner/.ccache
key: ccache-micropython-${{matrix.name}}-${{github.ref}}-${{github.sha}}
key: ccache-micropython-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
restore-keys: |
ccache-micropython-${{matrix.name}}-${{github.ref}}
ccache-micropython-${{matrix.name}}-
- name: Workspace Cache
uses: actions/cache@v3
with:
path: ${{runner.workspace}}
key: workspace-micropython-${{env.MICROPYTHON_VERSION}}-${{env.WORKFLOW_VERSION}}
restore-keys: |
workspace-micropython-${{env.MICROPYTHON_VERSION}}-${{env.WORKFLOW_VERSION}}
ccache-micropython-${{ matrix.name }}-${{ github.ref }}
ccache-micropython-${{ matrix.name }}-
- name: Install Compiler & CCache
if: runner.os == 'Linux'
run: |
sudo apt update && sudo apt install ccache gcc-arm-none-eabi
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
path: pimoroni-pico-${{ github.sha }}
- name: Set MicroPython Version Env Vars
shell: bash
- 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: |
echo "MICROPY_GIT_TAG=$MICROPYTHON_VERSION, ${{matrix.name}} ${{github.event.release.tag_name || github.sha}}" >> $GITHUB_ENV
echo "MICROPY_GIT_HASH=$MICROPYTHON_VERSION-${{github.event.release.tag_name || github.sha}}" >> $GITHUB_ENV
source $BUILD_TOOLS
apt_install_build_deps
- name: Checkout MicroPython & Submodules
run: |
source $BUILD_TOOLS
micropython_clone
- name: "Py_Decl: Checkout py_decl"
uses: actions/checkout@v4
with:
repository: gadgetoid/py_decl
ref: v0.0.1
path: py_decl
- name: Build MPY Cross
run: |
source $BUILD_TOOLS
micropython_build_mpy_cross
- name: "HACK: CMakeLists.txt Disable C++ Exceptions Patch"
shell: bash
working-directory: micropython
run: git apply $GITHUB_WORKSPACE/pimoroni-pico-${{ github.sha }}/micropython/micropython_nano_specs.patch
run: |
source $BUILD_TOOLS
hack_patch_micropython_disable_exceptions
- name: "HACK: Pico SDK Patch"
if: matrix.patch == true
shell: bash
working-directory: micropython
run: |
$GITHUB_WORKSPACE/pimoroni-pico-${{ github.sha }}/micropython/board/pico-sdk-patch.sh ${{matrix.board}}
source $BUILD_TOOLS
hack_patch_pico_sdk
- name: Configure MicroPython
shell: bash
working-directory: micropython/ports/rp2
run: |
cmake -S . -B build-${{matrix.name}} -DPICO_BUILD_DOCS=0 -DUSER_C_MODULES=${{env.USER_C_MODULES}} -DMICROPY_BOARD_DIR=${{env.MICROPY_BOARD_DIR}} -DMICROPY_BOARD=${{matrix.board}} -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
source $BUILD_TOOLS
micropython_version
cmake_configure
- name: Build MicroPython # Multiple simultaneous jobs trigger https://github.com/pimoroni/pimoroni-pico/issues/761
- name: Build MicroPython
shell: bash
working-directory: micropython/ports/rp2
run: |
ccache --zero-stats || true
cmake --build build-${{matrix.name}} -j 1
ccache --show-stats || true
source $BUILD_TOOLS
cmake_build
- name: Rename .uf2 for artifact
- name: "Py_Decl: Verify UF2"
shell: bash
working-directory: micropython/ports/rp2/build-${{matrix.name}}
run: |
cp firmware.uf2 $RELEASE_FILE.uf2
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@v3
uses: actions/upload-artifact@v4
with:
name: ${{env.RELEASE_FILE}}.uf2
path: micropython/ports/rp2/build-${{matrix.name}}/${{env.RELEASE_FILE}}.uf2
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}}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
asset_path: micropython/ports/rp2/build-${{matrix.name}}/firmware.uf2
upload_url: ${{github.event.release.upload_url}}
asset_name: ${{env.RELEASE_FILE}}.uf2
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

View File

@ -9,7 +9,7 @@ jobs:
name: Python Linting
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install Python Deps
run: python3 -m pip install flake8

View File

@ -10,6 +10,8 @@ set(CMAKE_CXX_STANDARD 17)
# Initialize the SDK
pico_sdk_init()
pico_find_compiler(PICO_COMPILER_LD ${PICO_GCC_TRIPLE}-ld)
function(add_resource target file)
get_filename_component(NAME ${ARGV1} NAME_WE)
set(FILENAME ${ARGV1})
@ -21,7 +23,7 @@ function(add_resource target file)
${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}
${CMAKE_CURRENT_BINARY_DIR}
COMMAND arm-none-eabi-ld -r -b binary -o ${NAME}.o ${FILENAME}
COMMAND ${PICO_COMPILER_LD} -r -b binary -o ${NAME}.o ${FILENAME}
DEPENDS ${FILENAME}
)

View File

@ -44,6 +44,10 @@ You can find MicroPython examples for supported sensors, packs and bases in the
* [MicroPython Examples](micropython/examples)
You can also install MicroPython stubs into Visual Studio Code to give you auto-complete, see:
* [MicroPython Stubs](https://github.com/pimoroni/pimoroni-pico-stubs)
# C/C++
Advanced users that want to unleash the full power of Pico can use our C++ libraries. If you know what you're doing and want to build your own Pimoroni Pico project then start with the [Pimoroni Pico SDK Boilerplate](https://github.com/pimoroni/pico-boilerplate).

75
ci/micropython.sh Normal file
View File

@ -0,0 +1,75 @@
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/micropython --depth=1 --branch=$MICROPYTHON_VERSION
cd micropython
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 hack_patch_micropython_disable_exceptions {
cd micropython
git apply $PIMORONI_PICO_DIR/micropython/micropython_nano_specs.patch
cd ../
}
function hack_patch_pico_sdk {
# pico-sdk-patch.sh will apply the patch if it exists
cd micropython
$PIMORONI_PICO_DIR/micropython/board/pico-sdk-patch.sh $MICROPY_BOARD
cd ../
}
function cmake_configure {
cmake -S micropython/ports/rp2 -B build-$BOARD_NAME \
-DPICO_BUILD_DOCS=0 \
-DUSER_C_MODULES=$USER_C_MODULES \
-DMICROPY_BOARD_DIR=$MICROPY_BOARD_DIR \
-DMICROPY_BOARD=$MICROPY_BOARD \
-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
}

View File

@ -41,6 +41,6 @@ add_subdirectory(pms5003)
add_subdirectory(sh1107)
add_subdirectory(st7567)
add_subdirectory(psram_display)
add_subdirectory(inky73)
add_subdirectory(shiftregister)
add_subdirectory(mlx90640)
add_subdirectory(inky73)
add_subdirectory(mlx90640)

View File

@ -4,7 +4,10 @@
#include "hardware/irq.h"
#include "hardware/clocks.h"
#include "encoder.hpp"
#ifndef NO_QSTR
#include "encoder.pio.h"
#endif
#define LAST_STATE(state) ((state) & 0b0011)
#define CURR_STATE(state) (((state) & 0b1100) >> 2)

View File

@ -113,12 +113,6 @@ void Hub75::FM6126A_setup() {
void Hub75::start(irq_handler_t handler) {
if(handler) {
dma_channel = 0;
// Try as I might, I can't seem to coax MicroPython into leaving PIO in a known state upon soft reset
// check for claimed PIO and prepare a clean slate.
stop(handler);
if (panel_type == PANEL_FM6126A) {
FM6126A_setup();
}
@ -139,7 +133,7 @@ void Hub75::start(irq_handler_t handler) {
// Prevent flicker in Python caused by the smaller dataset just blasting through the PIO too quickly
pio_sm_set_clkdiv(pio, sm_data, width <= 32 ? 2.0f : 1.0f);
dma_channel_claim(dma_channel);
dma_channel = dma_claim_unused_channel(true);
dma_channel_config config = dma_channel_get_default_config(dma_channel);
channel_config_set_transfer_data_size(&config, DMA_SIZE_32);
channel_config_set_bswap(&config, false);
@ -148,15 +142,13 @@ void Hub75::start(irq_handler_t handler) {
// Same handler for both DMA channels
irq_set_exclusive_handler(DMA_IRQ_0, handler);
irq_set_exclusive_handler(DMA_IRQ_1, handler);
irq_add_shared_handler(DMA_IRQ_0, handler, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
dma_channel_set_irq0_enabled(dma_channel, true);
irq_set_enabled(pio_get_dreq(pio, sm_data, true), true);
irq_set_enabled(DMA_IRQ_0, true);
row = 0;
bit = 0;
@ -169,10 +161,9 @@ void Hub75::start(irq_handler_t handler) {
void Hub75::stop(irq_handler_t handler) {
irq_set_enabled(DMA_IRQ_0, false);
irq_set_enabled(DMA_IRQ_1, false);
irq_set_enabled(pio_get_dreq(pio, sm_data, true), false);
if(dma_channel_is_claimed(dma_channel)) {
if(dma_channel != -1 && dma_channel_is_claimed(dma_channel)) {
dma_channel_set_irq0_enabled(dma_channel, false);
irq_remove_handler(DMA_IRQ_0, handler);
//dma_channel_wait_for_finish_blocking(dma_channel);
@ -184,17 +175,21 @@ void Hub75::stop(irq_handler_t handler) {
if(pio_sm_is_claimed(pio, sm_data)) {
pio_sm_set_enabled(pio, sm_data, false);
pio_sm_drain_tx_fifo(pio, sm_data);
pio_remove_program(pio, &hub75_data_rgb888_program, data_prog_offs);
pio_sm_unclaim(pio, sm_data);
}
if(pio_sm_is_claimed(pio, sm_row)) {
pio_sm_set_enabled(pio, sm_row, false);
pio_sm_drain_tx_fifo(pio, sm_row);
if (inverted_stb) {
pio_remove_program(pio, &hub75_row_inverted_program, row_prog_offs);
} else {
pio_remove_program(pio, &hub75_row_program, row_prog_offs);
}
pio_sm_unclaim(pio, sm_row);
}
pio_clear_instruction_memory(pio);
// Make sure the GPIO is in a known good state
// since we don't know what the PIO might have done with it
gpio_put_masked(0b111111 << pin_r0, 0);

View File

@ -5,7 +5,10 @@
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "libraries/pico_graphics/pico_graphics.hpp"
#ifndef NO_QSTR
#include "hub75.pio.h"
#endif
namespace pimoroni {
const uint DATA_BASE_PIN = 0;
@ -70,7 +73,7 @@ class Hub75 {
Pixel background = 0;
// DMA & PIO
uint dma_channel = 0;
int dma_channel = -1;
uint bit = 0;
uint row = 0;

View File

@ -4,7 +4,10 @@
#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#ifndef NO_QSTR
#include "hub75.pio.h"
#endif
const uint DATA_BASE_PIN = 0;
const uint DATA_N_PINS = 6;

View File

@ -1,3 +1,7 @@
if(NOT TARGET shiftregister)
include(${CMAKE_CURRENT_LIST_DIR}/../shiftregister/shiftregister.cmake)
endif()
set(DRIVER_NAME inky73)
add_library(${DRIVER_NAME} INTERFACE)

View File

@ -47,8 +47,9 @@ namespace pimoroni {
return !(sr.read() & 128);
}
void Inky73::busy_wait() {
while(is_busy()) {
void Inky73::busy_wait(uint timeout_ms) {
absolute_time_t timeout = make_timeout_time_ms(timeout_ms);
while(is_busy() && !time_reached(timeout)) {
tight_loop_contents();
}
}

View File

@ -70,7 +70,7 @@ namespace pimoroni {
// Methods
//--------------------------------------------------
public:
void busy_wait();
void busy_wait(uint timeout_ms=45000);
void reset();
void power_off();

View File

@ -1,3 +1,7 @@
if(NOT TARGET pwm)
include(${CMAKE_CURRENT_LIST_DIR}/../pwm/pwm.cmake)
endif()
set(DRIVER_NAME motor)
add_library(${DRIVER_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET pwm_cluster)
include(${CMAKE_CURRENT_LIST_DIR}/../pwm/pwm_cluster.cmake)
endif()
set(DRIVER_NAME motor_cluster)
add_library(${DRIVER_NAME} INTERFACE)

View File

@ -14,7 +14,9 @@ found here: https://github.com/raspberrypi/pico-examples/tree/master/pio/apa102
#include <math.h>
#include <cstdint>
#ifndef NO_QSTR
#include "apa102.pio.h"
#endif
#include "pico/stdlib.h"
#include "hardware/pio.h"

View File

@ -14,7 +14,9 @@ found here: https://github.com/raspberrypi/pico-examples/tree/master/pio/ws2812
#include <math.h>
#include <cstdint>
#ifndef NO_QSTR
#include "ws2812.pio.h"
#endif
#include "pico/stdlib.h"
#include "hardware/pio.h"

View File

@ -1,7 +1,10 @@
#include "pwm_cluster.hpp"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#ifndef NO_QSTR
#include "pwm_cluster.pio.h"
#endif
// Uncomment the below line to enable debugging
//#define DEBUG_MULTI_PWM

View File

@ -7,4 +7,4 @@ target_sources(rgbled INTERFACE
target_include_directories(rgbled INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(rgbled INTERFACE pico_stdlib hardware_pwm)
target_link_libraries(rgbled INTERFACE pico_stdlib hardware_pwm)

View File

@ -7,7 +7,9 @@
#define _PIO_SPI_H
#include "hardware/pio.h"
#ifndef NO_QSTR
#include "spi.pio.h"
#endif
typedef struct pio_spi_inst {
PIO pio;

View File

@ -1,3 +1,7 @@
if(NOT TARGET pwm)
include(${CMAKE_CURRENT_LIST_DIR}/../pwm/pwm.cmake)
endif()
set(DRIVER_NAME servo)
add_library(${DRIVER_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET pwm_cluster)
include(${CMAKE_CURRENT_LIST_DIR}/../pwm/pwm_cluster.cmake)
endif()
set(DRIVER_NAME servo_cluster)
add_library(${DRIVER_NAME} INTERFACE)

View File

@ -89,7 +89,6 @@ namespace pimoroni {
if(width == 320 && height == 240) {
command(reg::GCTRL, 1, "\x35");
command(reg::VCOMS, 1, "\x1f");
command(0xd6, 1, "\xa1"); // ???
command(reg::GMCTRP1, 14, "\xD0\x08\x11\x08\x0C\x15\x39\x33\x50\x36\x13\x14\x29\x2D");
command(reg::GMCTRN1, 14, "\xD0\x08\x10\x08\x06\x06\x39\x44\x51\x0B\x16\x14\x2F\x31");
}
@ -134,8 +133,6 @@ namespace pimoroni {
void ST7789::configure_display(Rotation rotate) {
bool rotate180 = rotate == ROTATE_180 || rotate == ROTATE_90;
if(rotate == ROTATE_90 || rotate == ROTATE_270) {
std::swap(width, height);
}
@ -186,20 +183,30 @@ namespace pimoroni {
// Pico Display
if(width == 240 && height == 135) {
caset[0] = 40; // 240 cols
caset[1] = 279;
raset[0] = 53; // 135 rows
raset[1] = 187;
madctl = rotate180 ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER;
caset[1] = 40 + width - 1;
raset[0] = 52; // 135 rows
raset[1] = 52 + height - 1;
if (rotate == ROTATE_0) {
raset[0] += 1;
raset[1] += 1;
}
madctl = rotate == ROTATE_180 ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER;
madctl |= MADCTL::SWAP_XY | MADCTL::SCAN_ORDER;
}
// Pico Display at 90 degree rotation
if(width == 135 && height == 240) {
caset[0] = 52; // 135 cols
caset[1] = 186;
caset[1] = 52 + width - 1;
raset[0] = 40; // 240 rows
raset[1] = 279;
madctl = rotate180 ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0;
raset[1] = 40 + height - 1;
madctl = 0;
if (rotate == ROTATE_90) {
caset[0] += 1;
caset[1] += 1;
madctl = MADCTL::COL_ORDER | MADCTL::ROW_ORDER;
}
madctl = rotate == ROTATE_90 ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0;
}
// Pico Display 2.0
@ -208,7 +215,7 @@ namespace pimoroni {
caset[1] = 319;
raset[0] = 0;
raset[1] = 239;
madctl = rotate180 ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER;
madctl = (rotate == ROTATE_180 || rotate == ROTATE_90) ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER;
madctl |= MADCTL::SWAP_XY | MADCTL::SCAN_ORDER;
}
@ -218,7 +225,7 @@ namespace pimoroni {
caset[1] = 239;
raset[0] = 0;
raset[1] = 319;
madctl = rotate180 ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0;
madctl = (rotate == ROTATE_180 || rotate == ROTATE_90) ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0;
}
// Byte swap the 16bit rows/cols values

View File

@ -11,7 +11,9 @@
#include "libraries/pico_graphics/pico_graphics.hpp"
#ifndef NO_QSTR
#include "st7789_parallel.pio.h"
#endif
#include <algorithm>

View File

@ -3,7 +3,11 @@
#include "pico_explorer.hpp"
#include "pico/stdlib.h"
#include "encoder.hpp"
#ifndef NO_QSTR
#include "quadrature_out.pio.h"
#endif
#include "drivers/st7789/st7789.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"
#include "button.hpp"

View File

@ -34,10 +34,15 @@ int main() {
while(true) {
offset += float(SPEED) / 2000.0f;
if (offset > 1.0) {
offset -= 1.0;
}
for(auto i = 0u; i < NUM_LEDS; ++i) {
float hue = float(i) / NUM_LEDS;
led_strip.set_hsv(i, hue + offset, 1.0f, 1.0f);
hue += offset;
hue -= floor(hue);
led_strip.set_hsv(i, hue, 1.0f, 1.0f);
}
sleep_ms(1000 / UPDATES);

View File

@ -1,12 +1,14 @@
add_library(automation INTERFACE)
target_sources(automation INTERFACE
${CMAKE_CURRENT_LIST_DIR}/automation.cpp
)
target_include_directories(automation INTERFACE ${CMAKE_CURRENT_LIST_DIR})
#include(${PIMORONI_PICO_PATH}/drivers/analog/analog.cmake)
# Pull in pico libraries that we need
target_link_libraries(automation INTERFACE pico_stdlib hardware_pwm hardware_i2c pimoroni_i2c analog)
if(NOT TARGET analog)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/analog/analog.cmake)
endif()
add_library(automation INTERFACE)
target_sources(automation INTERFACE
${CMAKE_CURRENT_LIST_DIR}/automation.cpp
)
target_include_directories(automation INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(automation INTERFACE pico_stdlib hardware_pwm hardware_i2c pimoroni_i2c analog)

View File

@ -1,11 +1,23 @@
set(LIB_NAME badger2040)
add_library(${LIB_NAME} INTERFACE)
target_sources(${LIB_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
)
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE bitmap_fonts hershey_fonts pico_stdlib hardware_pwm uc8151_legacy)
if(NOT TARGET uc8151_legacy)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/uc8151_legacy/uc8151_legacy.cmake)
endif()
if(NOT TARGET bitmap_fonts)
include(${CMAKE_CURRENT_LIST_DIR}/../bitmap_fonts/bitmap_fonts.cmake)
endif()
if(NOT TARGET hershey_fonts)
include(${CMAKE_CURRENT_LIST_DIR}/../hershey_fonts/hershey_fonts.cmake)
endif()
set(LIB_NAME badger2040)
add_library(${LIB_NAME} INTERFACE)
target_sources(${LIB_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
)
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE bitmap_fonts hershey_fonts uc8151_legacy pico_stdlib hardware_pwm)

View File

@ -152,6 +152,9 @@ namespace bitmap {
uint32_t line_offset = 0; // line (if wrapping) offset
unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195;
int32_t space_width = measure_character(font, ' ', scale, codepage, fixed_width);
space_width += letter_spacing * scale;
size_t i = 0;
while(i < t.length()) {
// find length of current word
@ -201,7 +204,7 @@ namespace bitmap {
line_offset += (font->height + 1) * scale;
char_offset = 0;
} else if (t[j] == ' ') { // Space
char_offset += font->widths[0] * scale;
char_offset += space_width;
} else {
switch(rotation) {
case 0:

View File

@ -1,3 +1,7 @@
if(NOT TARGET as7262)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/as7262/as7262.cmake)
endif()
set(LIB_NAME breakout_as7262)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET bh1745)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/bh1745/bh1745.cmake)
endif()
set(LIB_NAME breakout_bh1745)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET ltp305)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ltp305/ltp305.cmake)
endif()
set(LIB_NAME breakout_dotmatrix)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET ioexpander)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ioexpander/ioexpander.cmake)
endif()
set(LIB_NAME breakout_encoder)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,11 @@
if(NOT TARGET ioexpander)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ioexpander/ioexpander.cmake)
endif()
if(NOT TARGET is31fl3731)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/is31fl3731/is31fl3731.cmake)
endif()
set(LIB_NAME breakout_encoder_wheel)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET ioexpander)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ioexpander/ioexpander.cmake)
endif()
set(LIB_NAME breakout_ioexpander)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET ltr559)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ltr559/ltr559.cmake)
endif()
set(LIB_NAME breakout_ltr559)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET is31fl3731)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/is31fl3731/is31fl3731.cmake)
endif()
set(LIB_NAME breakout_matrix11x7)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET ioexpander)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ioexpander/ioexpander.cmake)
endif()
set(LIB_NAME breakout_mics6814)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET msa301)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/msa301/msa301.cmake)
endif()
set(LIB_NAME breakout_msa301)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET pmw3901)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/pmw3901/pmw3901.cmake)
endif()
set(LIB_NAME breakout_paa5100)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET pmw3901)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/pmw3901/pmw3901.cmake)
endif()
set(LIB_NAME breakout_pmw3901)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET ioexpander)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/ioexpander/ioexpander.cmake)
endif()
set(LIB_NAME breakout_potentiometer)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET is31fl3731)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/is31fl3731/is31fl3731.cmake)
endif()
set(LIB_NAME breakout_rgbmatrix5x5)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET rv3028)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/rv3028/rv3028.cmake)
endif()
set(LIB_NAME breakout_rtc)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET sgp30)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/sgp30/sgp30.cmake)
endif()
set(LIB_NAME breakout_sgp30)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET trackball)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/trackball/trackball.cmake)
endif()
set(LIB_NAME breakout_trackball)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,7 @@
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
add_library(cosmic_unicorn INTERFACE)
pico_generate_pio_header(cosmic_unicorn ${CMAKE_CURRENT_LIST_DIR}/cosmic_unicorn.pio)

View File

@ -6,8 +6,10 @@
#include "hardware/clocks.h"
#ifndef NO_QSTR
#include "cosmic_unicorn.pio.h"
#include "audio_i2s.pio.h"
#endif
#include "cosmic_unicorn.hpp"
@ -492,11 +494,14 @@ namespace pimoroni {
void CosmicUnicorn::set_brightness(float value) {
value = value < 0.0f ? 0.0f : value;
value = value > 1.0f ? 1.0f : value;
// Max brightness is - in fact - 256 since it's applied with:
// result = (channel * brightness) >> 8
// eg: (255 * 256) >> 8 == 255
this->brightness = floor(value * 256.0f);
}
float CosmicUnicorn::get_brightness() {
return this->brightness / 255.0f;
return this->brightness / 256.0f;
}
void CosmicUnicorn::adjust_brightness(float delta) {

View File

@ -1,3 +1,7 @@
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
add_library(galactic_unicorn INTERFACE)
pico_generate_pio_header(galactic_unicorn ${CMAKE_CURRENT_LIST_DIR}/galactic_unicorn.pio)

View File

@ -6,8 +6,10 @@
#include "hardware/clocks.h"
#ifndef NO_QSTR
#include "galactic_unicorn.pio.h"
#include "audio_i2s.pio.h"
#endif
#include "galactic_unicorn.hpp"
@ -486,11 +488,14 @@ namespace pimoroni {
void GalacticUnicorn::set_brightness(float value) {
value = value < 0.0f ? 0.0f : value;
value = value > 1.0f ? 1.0f : value;
// Max brightness is - in fact - 256 since it's applied with:
// result = (channel * brightness) >> 8
// eg: (255 * 256) >> 8 == 255
this->brightness = floor(value * 256.0f);
}
float GalacticUnicorn::get_brightness() {
return this->brightness / 255.0f;
return this->brightness / 256.0f;
}
void GalacticUnicorn::adjust_brightness(float delta) {

View File

@ -1,3 +1,19 @@
if(NOT TARGET st7567)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/st7567/st7567.cmake)
endif()
if(NOT TARGET button)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/button/button.cmake)
endif()
if(NOT TARGET rgbled)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/rgbled/rgbled.cmake)
endif()
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
set(LIB_NAME gfx_pack)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,11 +1,35 @@
set(LIB_NAME inky_frame)
add_library(${LIB_NAME} INTERFACE)
target_sources(${LIB_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
)
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE hardware_i2c pico_graphics hardware_spi hardware_pwm bitmap_fonts hershey_fonts pico_stdlib sdcard fatfs pcf85063a uc8159 jpegdec)
if(NOT TARGET sdcard)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/sdcard/sdcard.cmake)
endif()
if(NOT TARGET fatfs)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/fatfs/fatfs.cmake)
endif()
if(NOT TARGET pcf85063a)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/pcf85063a/pcf85063a.cmake)
endif()
if(NOT TARGET uc8159)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/uc8159/uc8159.cmake)
endif()
if(NOT TARGET jpegdec)
include(${CMAKE_CURRENT_LIST_DIR}/../jpegdec/jpegdec.cmake)
endif()
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
set(LIB_NAME inky_frame)
add_library(${LIB_NAME} INTERFACE)
target_sources(${LIB_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
)
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE hardware_i2c pico_graphics hardware_spi hardware_pwm bitmap_fonts hershey_fonts pico_stdlib sdcard fatfs pcf85063a uc8159 jpegdec)

View File

@ -1,13 +1,41 @@
set(LIB_NAME inky_frame_7)
add_library(${LIB_NAME} INTERFACE)
target_sources(${LIB_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
)
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE hardware_i2c pico_graphics hardware_spi hardware_pwm bitmap_fonts hershey_fonts pico_stdlib sdcard fatfs pcf85063a psram_display inky73 jpegdec)
if(NOT TARGET sdcard)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/sdcard/sdcard.cmake)
endif()
if(NOT TARGET fatfs)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/fatfs/fatfs.cmake)
endif()
if(NOT TARGET pcf85063a)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/pcf85063a/pcf85063a.cmake)
endif()
if(NOT TARGET psram_display)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/psram_display/psram_display.cmake)
endif()
if(NOT TARGET inky73)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/inky73/inky73.cmake)
endif()
if(NOT TARGET jpegdec)
include(${CMAKE_CURRENT_LIST_DIR}/../jpegdec/jpegdec.cmake)
endif()
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
set(LIB_NAME inky_frame_7)
add_library(${LIB_NAME} INTERFACE)
target_sources(${LIB_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp
)
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(${LIB_NAME} INTERFACE hardware_i2c pico_graphics hardware_spi hardware_pwm bitmap_fonts hershey_fonts pico_stdlib sdcard fatfs pcf85063a psram_display inky73 jpegdec)
target_compile_options(${LIB_NAME} INTERFACE -Wno-error=reorder)

View File

@ -1,3 +1,19 @@
if(NOT TARGET hub75)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/hub75/hub75.cmake)
endif()
if(NOT TARGET button)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/button/button.cmake)
endif()
if(NOT TARGET rgbled)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/rgbled/rgbled.cmake)
endif()
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
set(LIB_NAME interstate75)
add_library(${LIB_NAME} INTERFACE)

View File

@ -1,3 +1,19 @@
if(NOT TARGET motor)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/motor/motor.cmake)
endif()
if(NOT TARGET servo)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/servo/servo.cmake)
endif()
if(NOT TARGET encoder)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/encoder/encoder.cmake)
endif()
if(NOT TARGET plasma)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/plasma/plasma.cmake)
endif()
add_library(inventor INTERFACE)
target_sources(inventor INTERFACE
@ -7,4 +23,4 @@ target_sources(inventor INTERFACE
target_include_directories(inventor INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need
target_link_libraries(inventor INTERFACE pico_stdlib hardware_pwm hardware_pio hardware_i2c pimoroni_i2c motor servo encoder plasma pimoroni_i2c)
target_link_libraries(inventor INTERFACE pico_stdlib hardware_pwm hardware_pio hardware_i2c pimoroni_i2c motor servo encoder plasma)

View File

@ -68,6 +68,7 @@
enum {
RGB565_LITTLE_ENDIAN = 0,
RGB565_BIG_ENDIAN,
RGB888_LITTLE_ENDIAN,
EIGHT_BIT_GRAYSCALE,
FOUR_BIT_DITHERED,
TWO_BIT_DITHERED,

View File

@ -182,138 +182,82 @@ static const uint16_t usGrayTo565[] = {0x0000,0x0000,0x0000,0x0000,0x0020,0x0020
//
// Clip and convert red value into 5-bits for RGB565
//
static const uint16_t usRangeTableR[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // 0
0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,
0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,
0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,
0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,
0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,
0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,
0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,
0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,
0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,
0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,
0x5800,0x5800,0x5800,0x5800,0x5800,0x5800,0x5800,0x5800,
0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,
0x6800,0x6800,0x6800,0x6800,0x6800,0x6800,0x6800,0x6800,
0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,
0x7800,0x7800,0x7800,0x7800,0x7800,0x7800,0x7800,0x7800,
0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,
0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,
0x9000,0x9000,0x9000,0x9000,0x9000,0x9000,0x9000,0x9000,
0x9800,0x9800,0x9800,0x9800,0x9800,0x9800,0x9800,0x9800,
0xa000,0xa000,0xa000,0xa000,0xa000,0xa000,0xa000,0xa000,
0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,
0xb000,0xb000,0xb000,0xb000,0xb000,0xb000,0xb000,0xb000,
0xb800,0xb800,0xb800,0xb800,0xb800,0xb800,0xb800,0xb800,
0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,
0xc800,0xc800,0xc800,0xc800,0xc800,0xc800,0xc800,0xc800,
0xd000,0xd000,0xd000,0xd000,0xd000,0xd000,0xd000,0xd000,
0xd800,0xd800,0xd800,0xd800,0xd800,0xd800,0xd800,0xd800,
0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,
0xe800,0xe800,0xe800,0xe800,0xe800,0xe800,0xe800,0xe800,
0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // 256
static const uint16_t usRangeTableR[] = {0x0000, // 0
0x0800,
0x1000,
0x1800,
0x2000,
0x2800,
0x3000,
0x3800,
0x4000,
0x4800,
0x5000,
0x5800,
0x6000,
0x6800,
0x7000,
0x7800,
0x8000,
0x8800,
0x9000,
0x9800,
0xa000,
0xa800,
0xb000,
0xb800,
0xc000,
0xc800,
0xd000,
0xd800,
0xe000,
0xe800,
0xf000,
0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // 32
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 512
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 768
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 64
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 96
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//
// Clip and convert green value into 5-bits for RGB565
// Clip and convert green value into 6-bits for RGB565
//
static const uint16_t usRangeTableG[] = {0x0000,0x0000,0x0000,0x0000,0x0020,0x0020,0x0020,0x0020, // 0
0x0040,0x0040,0x0040,0x0040,0x0060,0x0060,0x0060,0x0060,
0x0080,0x0080,0x0080,0x0080,0x00a0,0x00a0,0x00a0,0x00a0,
0x00c0,0x00c0,0x00c0,0x00c0,0x00e0,0x00e0,0x00e0,0x00e0,
0x0100,0x0100,0x0100,0x0100,0x0120,0x0120,0x0120,0x0120,
0x0140,0x0140,0x0140,0x0140,0x0160,0x0160,0x0160,0x0160,
0x0180,0x0180,0x0180,0x0180,0x01a0,0x01a0,0x01a0,0x01a0,
0x01c0,0x01c0,0x01c0,0x01c0,0x01e0,0x01e0,0x01e0,0x01e0,
0x0200,0x0200,0x0200,0x0200,0x0220,0x0220,0x0220,0x0220,
0x0240,0x0240,0x0240,0x0240,0x0260,0x0260,0x0260,0x0260,
0x0280,0x0280,0x0280,0x0280,0x02a0,0x02a0,0x02a0,0x02a0,
0x02c0,0x02c0,0x02c0,0x02c0,0x02e0,0x02e0,0x02e0,0x02e0,
0x0300,0x0300,0x0300,0x0300,0x0320,0x0320,0x0320,0x0320,
0x0340,0x0340,0x0340,0x0340,0x0360,0x0360,0x0360,0x0360,
0x0380,0x0380,0x0380,0x0380,0x03a0,0x03a0,0x03a0,0x03a0,
0x03c0,0x03c0,0x03c0,0x03c0,0x03e0,0x03e0,0x03e0,0x03e0,
0x0400,0x0400,0x0400,0x0400,0x0420,0x0420,0x0420,0x0420,
0x0440,0x0440,0x0440,0x0440,0x0460,0x0460,0x0460,0x0460,
0x0480,0x0480,0x0480,0x0480,0x04a0,0x04a0,0x04a0,0x04a0,
0x04c0,0x04c0,0x04c0,0x04c0,0x04e0,0x04e0,0x04e0,0x04e0,
0x0500,0x0500,0x0500,0x0500,0x0520,0x0520,0x0520,0x0520,
0x0540,0x0540,0x0540,0x0540,0x0560,0x0560,0x0560,0x0560,
0x0580,0x0580,0x0580,0x0580,0x05a0,0x05a0,0x05a0,0x05a0,
0x05c0,0x05c0,0x05c0,0x05c0,0x05e0,0x05e0,0x05e0,0x05e0,
0x0600,0x0600,0x0600,0x0600,0x0620,0x0620,0x0620,0x0620,
0x0640,0x0640,0x0640,0x0640,0x0660,0x0660,0x0660,0x0660,
0x0680,0x0680,0x0680,0x0680,0x06a0,0x06a0,0x06a0,0x06a0,
0x06c0,0x06c0,0x06c0,0x06c0,0x06e0,0x06e0,0x06e0,0x06e0,
0x0700,0x0700,0x0700,0x0700,0x0720,0x0720,0x0720,0x0720,
0x0740,0x0740,0x0740,0x0740,0x0760,0x0760,0x0760,0x0760,
0x0780,0x0780,0x0780,0x0780,0x07a0,0x07a0,0x07a0,0x07a0,
0x07c0,0x07c0,0x07c0,0x07c0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // 256
static const uint16_t usRangeTableG[] = {0x0000,0x0020, // 0
0x0040,0x0060,
0x0080,0x00a0,
0x00c0,0x00e0,
0x0100,0x0120,
0x0140,0x0160,
0x0180,0x01a0,
0x01c0,0x01e0,
0x0200,0x0220,
0x0240,0x0260,
0x0280,0x02a0,
0x02c0,0x02e0,
0x0300,0x0320,
0x0340,0x0360,
0x0380,0x03a0,
0x03c0,0x03e0,
0x0400,0x0420,
0x0440,0x0460,
0x0480,0x04a0,
0x04c0,0x04e0,
0x0500,0x0520,
0x0540,0x0560,
0x0580,0x05a0,
0x05c0,0x05e0,
0x0600,0x0620,
0x0640,0x0660,
0x0680,0x06a0,
0x06c0,0x06e0,
0x0700,0x0720,
0x0740,0x0760,
0x0780,0x07a0,
0x07c0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // 64
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
@ -321,160 +265,56 @@ static const uint16_t usRangeTableG[] = {0x0000,0x0000,0x0000,0x0000,0x0020,0x00
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 512
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 768
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 128
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 196
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//
// Clip and convert blue value into 5-bits for RGB565
//
static const uint16_t usRangeTableB[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // 0
0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,
0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,
0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,
0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,
0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,
0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,
0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,
0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,
0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,
0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,
0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,
0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,
0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,
0x0011,0x0011,0x0011,0x0011,0x0011,0x0011,0x0011,0x0011,
0x0012,0x0012,0x0012,0x0012,0x0012,0x0012,0x0012,0x0012,
0x0013,0x0013,0x0013,0x0013,0x0013,0x0013,0x0013,0x0013,
0x0014,0x0014,0x0014,0x0014,0x0014,0x0014,0x0014,0x0014,
0x0015,0x0015,0x0015,0x0015,0x0015,0x0015,0x0015,0x0015,
0x0016,0x0016,0x0016,0x0016,0x0016,0x0016,0x0016,0x0016,
0x0017,0x0017,0x0017,0x0017,0x0017,0x0017,0x0017,0x0017,
0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,
0x0019,0x0019,0x0019,0x0019,0x0019,0x0019,0x0019,0x0019,
0x001a,0x001a,0x001a,0x001a,0x001a,0x001a,0x001a,0x001a,
0x001b,0x001b,0x001b,0x001b,0x001b,0x001b,0x001b,0x001b,
0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,
0x001d,0x001d,0x001d,0x001d,0x001d,0x001d,0x001d,0x001d,
0x001e,0x001e,0x001e,0x001e,0x001e,0x001e,0x001e,0x001e,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f, // 256
static const uint16_t usRangeTableB[] = {0x0000, // 0
0x0001,
0x0002,
0x0003,
0x0004,
0x0005,
0x0006,
0x0007,
0x0008,
0x0009,
0x000a,
0x000b,
0x000c,
0x000d,
0x000e,
0x000f,
0x0010,
0x0011,
0x0012,
0x0013,
0x0014,
0x0015,
0x0016,
0x0017,
0x0018,
0x0019,
0x001a,
0x001b,
0x001c,
0x001d,
0x001e,
0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f, // 32
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,0x001f,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 512
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 768
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 64
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 96
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
#if defined (__MACH__) || defined( __LINUX__ ) || defined( __MCUXPRESSO )
//
@ -2288,9 +2128,9 @@ static void JPEGPixelLE(uint16_t *pDest, int iY, int iCb, int iCr)
iCBG = -1409 * (iCb-0x80);
iCRG = -2925 * (iCr-0x80);
iCRR = 5742 * (iCr-0x80);
usPixel = usRangeTableB[((iCBB + iY) >> 12) & 0x3ff]; // blue pixel
usPixel |= usRangeTableG[((iCBG + iCRG + iY) >> 12) & 0x3ff]; // green pixel
usPixel |= usRangeTableR[((iCRR + iY) >> 12) & 0x3ff]; // red pixel
usPixel = usRangeTableB[((iCBB + iY) >> 15) & 0x7f]; // blue pixel
usPixel |= usRangeTableG[((iCBG + iCRG + iY) >> 14) & 0xff]; // green pixel
usPixel |= usRangeTableR[((iCRR + iY) >> 15) & 0x7f]; // red pixel
pDest[0] = usPixel;
#endif
} /* JPEGPixelLE() */
@ -2304,9 +2144,9 @@ static void JPEGPixelBE(uint16_t *pDest, int iY, int iCb, int iCr)
iCBG = -1409 * (iCb-0x80);
iCRG = -2925 * (iCr-0x80);
iCRR = 5742 * (iCr-0x80);
usPixel = usRangeTableB[((iCBB + iY) >> 12) & 0x3ff]; // blue pixel
usPixel |= usRangeTableG[((iCBG + iCRG + iY) >> 12) & 0x3ff]; // green pixel
usPixel |= usRangeTableR[((iCRR + iY) >> 12) & 0x3ff]; // red pixel
usPixel = usRangeTableB[((iCBB + iY) >> 15) & 0x7f]; // blue pixel
usPixel |= usRangeTableG[((iCBG + iCRG + iY) >> 14) & 0xff]; // green pixel
usPixel |= usRangeTableR[((iCRR + iY) >> 15) & 0x7f]; // red pixel
pDest[0] = __builtin_bswap16(usPixel);
} /* JPEGPixelBE() */
@ -2340,13 +2180,13 @@ static void JPEGPixel2LE(uint16_t *pDest, int iY1, int iY2, int iCb, int iCr)
iCBG = -1409 * (iCb-0x80);
iCRG = -2925 * (iCr-0x80);
iCRR = 5742 * (iCr-0x80);
ulPixel1 = usRangeTableB[((iCBB + iY1) >> 12) & 0x3ff]; // blue pixel
ulPixel1 |= usRangeTableG[((iCBG + iCRG + iY1) >> 12) & 0x3ff]; // green pixel
ulPixel1 |= usRangeTableR[((iCRR + iY1) >> 12) & 0x3ff]; // red pixel
ulPixel1 = usRangeTableB[((iCBB + iY1) >> 15) & 0x7f]; // blue pixel
ulPixel1 |= usRangeTableG[((iCBG + iCRG + iY1) >> 14) & 0xff]; // green pixel
ulPixel1 |= usRangeTableR[((iCRR + iY1) >> 15) & 0x7f]; // red pixel
ulPixel2 = usRangeTableB[((iCBB + iY2) >> 12) & 0x3ff]; // blue pixel
ulPixel2 |= usRangeTableG[((iCBG + iCRG + iY2) >> 12) & 0x3ff]; // green pixel
ulPixel2 |= usRangeTableR[((iCRR + iY2) >> 12) & 0x3ff]; // red pixel
ulPixel2 = usRangeTableB[((iCBB + iY2) >> 15) & 0x7f]; // blue pixel
ulPixel2 |= usRangeTableG[((iCBG + iCRG + iY2) >> 14) & 0xff]; // green pixel
ulPixel2 |= usRangeTableR[((iCRR + iY2) >> 15) & 0x7f]; // red pixel
*(uint32_t *)&pDest[0] = (ulPixel1 | (ulPixel2<<16));
#endif
} /* JPEGPixel2LE() */
@ -2360,16 +2200,42 @@ static void JPEGPixel2BE(uint16_t *pDest, int32_t iY1, int32_t iY2, int32_t iCb,
iCBG = -1409L * (iCb-0x80);
iCRG = -2925L * (iCr-0x80);
iCRR = 5742L * (iCr-0x80);
ulPixel1 = usRangeTableB[((iCBB + iY1) >> 12) & 0x3ff]; // blue pixel
ulPixel1 |= usRangeTableG[((iCBG + iCRG + iY1) >> 12) & 0x3ff]; // green pixel
ulPixel1 |= usRangeTableR[((iCRR + iY1) >> 12) & 0x3ff]; // red pixel
ulPixel1 = usRangeTableB[((iCBB + iY1) >> 15) & 0x7f]; // blue pixel
ulPixel1 |= usRangeTableG[((iCBG + iCRG + iY1) >> 14) & 0xff]; // green pixel
ulPixel1 |= usRangeTableR[((iCRR + iY1) >> 15) & 0x7f]; // red pixel
ulPixel2 = usRangeTableB[((iCBB + iY2) >> 12) & 0x3ff]; // blue pixel
ulPixel2 |= usRangeTableG[((iCBG + iCRG + iY2) >> 12) & 0x3ff]; // green pixel
ulPixel2 |= usRangeTableR[((iCRR + iY2) >> 12) & 0x3ff]; // red pixel
ulPixel2 = usRangeTableB[((iCBB + iY2) >> 15) & 0x7f]; // blue pixel
ulPixel2 |= usRangeTableG[((iCBG + iCRG + iY2) >> 14) & 0xff]; // green pixel
ulPixel2 |= usRangeTableR[((iCRR + iY2) >> 15) & 0x7f]; // red pixel
*(uint32_t *)&pDest[0] = __builtin_bswap16(ulPixel1) | ((uint32_t)__builtin_bswap16(ulPixel2)<<16);
} /* JPEGPixel2BE() */
static void JPEGPixelLE888(uint8_t *pDest, int iY, int iCb, int iCr)
{
int32_t iCBB, iCBG, iCRG, iCRR;
uint32_t uVal;
iCBB = 7258 * (iCb-0x80);
iCBG = -1409 * (iCb-0x80);
iCRG = -2925 * (iCr-0x80);
iCRR = 5742 * (iCr-0x80);
// Red
uVal = ((iCRR + iY) >> 13) & 0x1FF;
if (uVal & 0x100) uVal = 0;
*pDest++ = uVal;
// Green
uVal = ((iCBG + iCRG + iY) >> 13) & 0x1FF;
if (uVal & 0x100) uVal = 0;
*pDest++ = uVal;
// Blue
uVal = ((iCBB + iY) >> 13) & 0x1FF;
if (uVal & 0x100) uVal = 0;
*pDest++ = uVal;
}
static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
{
int iCr, iCb;
@ -2378,6 +2244,7 @@ static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
int iRow;
uint8_t *pY, *pCr, *pCb;
uint16_t *pOutput = &pJPEG->usPixels[x];
uint8_t *pOutput8 = ((uint8_t*)pJPEG->usPixels) + x * 3;
pY = (unsigned char *)&pJPEG->sMCUs[0*DCTSIZE];
pCb = (unsigned char *)&pJPEG->sMCUs[1*DCTSIZE];
@ -2474,6 +2341,17 @@ static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
JPEGPixelLE(pOutput+iCol, Y, iCb, iCr);
} // for col
}
else if (pJPEG->ucPixelType == RGB888_LITTLE_ENDIAN)
{
for (iCol=0; iCol<8; iCol++) // up to 4x2 cols to do
{
iCr = *pCr++;
iCb = *pCb++;
Y = (int)(*pY++) << 12;
JPEGPixelLE888(pOutput8+iCol*3, Y, iCb, iCr);
} // for col
pOutput8 += iPitch * 3;
}
else
{
for (iCol=0; iCol<8; iCol++) // up to 4x2 cols to do
@ -2829,6 +2707,7 @@ static void JPEGPutMCU12(JPEGIMAGE *pJPEG, int x, int iPitch)
int iRow, iCol, iXCount, iYCount;
uint8_t *pY, *pCr, *pCb;
uint16_t *pOutput = &pJPEG->usPixels[x];
uint8_t *pOutput8 = ((uint8_t*)pJPEG->usPixels) + x * 3;
pY = (uint8_t *)&pJPEG->sMCUs[0*DCTSIZE];
pCb = (uint8_t *)&pJPEG->sMCUs[2*DCTSIZE];
@ -2960,6 +2839,11 @@ static void JPEGPutMCU12(JPEGIMAGE *pJPEG, int x, int iPitch)
JPEGPixelLE(pOutput + iCol, Y1, Cb, Cr);
JPEGPixelLE(pOutput + iPitch + iCol, Y2, Cb, Cr);
}
else if (pJPEG->ucPixelType == RGB888_LITTLE_ENDIAN)
{
JPEGPixelLE888(pOutput8 + iCol*3, Y1, Cb, Cr);
JPEGPixelLE888(pOutput8 + (iPitch + iCol)*3, Y2, Cb, Cr);
}
else
{
JPEGPixelBE(pOutput + iCol, Y1, Cb, Cr);
@ -2972,6 +2856,7 @@ static void JPEGPutMCU12(JPEGIMAGE *pJPEG, int x, int iPitch)
pCb += 8;
pCr += 8;
pOutput += iPitch*2; // next 2 lines of dest pixels
pOutput8 += iPitch*6;
}
} /* JPEGPutMCU12() */
static void JPEGPutMCU21(JPEGIMAGE *pJPEG, int x, int iPitch)
@ -3229,6 +3114,8 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG)
cDCTable2 = pJPEG->JPCI[2].dc_tbl_no;
cACTable2 = pJPEG->JPCI[2].ac_tbl_no;
iDCPred0 = iDCPred1 = iDCPred2 = mcuCX = mcuCY = 0;
printf("SubSample mode: 0x%x\n", pJPEG->ucSubSample);
switch (pJPEG->ucSubSample) // set up the parameters for the different subsampling options
{
@ -3287,6 +3174,8 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG)
iMCUCount = MAX_BUFFERED_PIXELS / (mcuCX * mcuCY);
if (pJPEG->ucPixelType == EIGHT_BIT_GRAYSCALE)
iMCUCount *= 2; // each pixel is only 1 byte
else if (pJPEG->ucPixelType == RGB888_LITTLE_ENDIAN)
iMCUCount = (iMCUCount >> 1) + (iMCUCount >> 3); // each picel is 3 bytes
if (iMCUCount > cx)
iMCUCount = cx; // don't go wider than the image
if (iMCUCount > pJPEG->iMaxMCUs) // did the user set an upper bound on how many pixels per JPEGDraw callback?
@ -3296,6 +3185,9 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG)
jd.iBpp = 16;
switch (pJPEG->ucPixelType)
{
case RGB888_LITTLE_ENDIAN:
jd.iBpp = 24;
break;
case EIGHT_BIT_GRAYSCALE:
jd.iBpp = 8;
break;

View File

@ -1,3 +1,19 @@
if(NOT TARGET plasma)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/plasma/plasma.cmake)
endif()
if(NOT TARGET motor)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/motor/motor.cmake)
endif()
if(NOT TARGET motor_cluster)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/motor/motor_cluster.cmake)
endif()
if(NOT TARGET encoder)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/encoder/encoder.cmake)
endif()
add_library(motor2040 INTERFACE)
target_include_directories(motor2040 INTERFACE ${CMAKE_CURRENT_LIST_DIR})

View File

@ -47,6 +47,10 @@ namespace motor {
const uint LED_DATA = 18;
const uint NUM_LEDS = 1;
const uint I2C_INT = 19;
const uint I2C_SDA = 20;
const uint I2C_SCL = 21;
const uint USER_SW = 23;
const uint ADC_ADDR_0 = 22;

View File

@ -1,5 +1,10 @@
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/st7789/st7789.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
if(NOT TARGET st7789)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/st7789/st7789.cmake)
endif()
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
add_library(pico_explorer INTERFACE)

View File

@ -8,6 +8,7 @@ namespace pimoroni {
int PicoGraphics::reset_pen(uint8_t i) {return -1;};
int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) {return -1;};
int PicoGraphics::create_pen_hsv(float h, float s, float v){return -1;};
void PicoGraphics::set_pixel_alpha(const Point &p, const uint8_t a) {};
void PicoGraphics::set_pixel_dither(const Point &p, const RGB &c) {};
void PicoGraphics::set_pixel_dither(const Point &p, const RGB565 &c) {};
void PicoGraphics::set_pixel_dither(const Point &p, const uint8_t &c) {};
@ -16,6 +17,7 @@ namespace pimoroni {
int PicoGraphics::get_palette_size() {return 0;}
RGB* PicoGraphics::get_palette() {return nullptr;}
bool PicoGraphics::supports_alpha_blend() {return false;}
void PicoGraphics::set_dimensions(int width, int height) {
bounds = clip = {0, 0, width, height};
@ -266,7 +268,7 @@ namespace pimoroni {
int32_t ex = points[j].x;
int32_t px = int32_t(sx + float(fy - sy) / float(ey - sy) * float(ex - sx));
nodes[n++] = px < clip.x ? clip.x : (px >= clip.x + clip.w ? clip.x + clip.w - 1 : px);// clamp(int32_t(sx + float(fy - sy) / float(ey - sy) * float(ex - sx)), clip.x, clip.x + clip.w);
nodes[n++] = px;
}
}

View File

@ -26,6 +26,7 @@
namespace pimoroni {
typedef uint8_t RGB332;
typedef uint16_t RGB565;
typedef uint16_t RGB555;
typedef uint32_t RGB888;
@ -46,7 +47,19 @@ namespace pimoroni {
g((c >> 8) & 0xff),
b(c & 0xff) {}
constexpr RGB(int16_t r, int16_t g, int16_t b) : r(r), g(g), b(b) {}
constexpr uint8_t blend(uint8_t s, uint8_t d, uint8_t a) {
return d + ((a * (s - d) + 127) >> 8);
}
constexpr RGB blend(RGB with, const uint8_t alpha) {
return RGB(
blend(with.r, r, alpha),
blend(with.g, g, alpha),
blend(with.b, b, alpha)
);
}
static RGB from_hsv(float h, float s, float v) {
float i = floor(h * 6.0f);
float f = h * 6.0f - i;
@ -108,6 +121,14 @@ namespace pimoroni {
return __builtin_bswap16(p);
}
constexpr RGB555 to_rgb555() {
uint16_t p = ((r & 0b11111000) << 7) |
((g & 0b11111000) << 2) |
((b & 0b11111000) >> 3);
return p;
}
constexpr RGB565 to_rgb332() {
return (r & 0b11100000) | ((g & 0b11100000) >> 3) | ((b & 0b11000000) >> 6);
}
@ -192,7 +213,10 @@ namespace pimoroni {
PEN_RGB332,
PEN_RGB565,
PEN_RGB888,
PEN_INKY7
PEN_INKY7,
PEN_DV_RGB555,
PEN_DV_P5,
PEN_DV_RGB888,
};
void *frame_buffer;
@ -256,6 +280,7 @@ namespace pimoroni {
virtual int get_palette_size();
virtual RGB* get_palette();
virtual bool supports_alpha_blend();
virtual int create_pen(uint8_t r, uint8_t g, uint8_t b);
virtual int create_pen_hsv(float h, float s, float v);
@ -264,9 +289,12 @@ namespace pimoroni {
virtual void set_pixel_dither(const Point &p, const RGB &c);
virtual void set_pixel_dither(const Point &p, const RGB565 &c);
virtual void set_pixel_dither(const Point &p, const uint8_t &c);
virtual void set_pixel_alpha(const Point &p, const uint8_t a);
virtual void frame_convert(PenType type, conversion_callback_func callback);
virtual void sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent);
virtual bool render_pico_vector_tile(const Rect &bounds, uint8_t* alpha_data, uint32_t stride, uint8_t alpha_type) { return false; }
void set_font(const bitmap::font_t *font);
void set_font(const hershey::font_t *font);
void set_font(std::string_view name);
@ -459,6 +487,9 @@ namespace pimoroni {
void set_pixel_span(const Point &p, uint l) override;
void set_pixel_dither(const Point &p, const RGB &c) override;
void set_pixel_dither(const Point &p, const RGB565 &c) override;
void set_pixel_alpha(const Point &p, const uint8_t a) override;
bool supports_alpha_blend() override {return true;}
void sprite(void* data, const Point &sprite, const Point &dest, const int scale, const int transparent) override;
@ -528,6 +559,12 @@ namespace pimoroni {
virtual void read_pixel_span(const Point &p, uint l, T *data) {};
};
class IPaletteDisplayDriver {
public:
virtual void write_palette_pixel(const Point &p, uint8_t colour) = 0;
virtual void write_palette_pixel_span(const Point &p, uint l, uint8_t colour) = 0;
virtual void set_palette_colour(uint8_t entry, RGB888 colour) = 0;
};
class PicoGraphics_PenInky7 : public PicoGraphics {
public:

View File

@ -15,7 +15,7 @@ namespace pimoroni {
}
void PicoGraphics_Pen1BitY::set_pen(uint8_t r, uint8_t g, uint8_t b) {
color = std::max(r, std::max(g, b));
color = std::max(r, std::max(g, b)) >> 4;
}
void PicoGraphics_Pen1BitY::set_pixel(const Point &p) {

View File

@ -34,6 +34,15 @@ namespace pimoroni {
*buf++ = color;
}
}
void PicoGraphics_PenRGB332::set_pixel_alpha(const Point &p, const uint8_t a) {
if(!bounds.contains(p)) return;
uint8_t *buf = (uint8_t *)frame_buffer;
RGB332 blended = RGB(buf[p.y * bounds.w + p.x]).blend(RGB(color), a).to_rgb332();
buf[p.y * bounds.w + p.x] = blended;
};
void PicoGraphics_PenRGB332::set_pixel_dither(const Point &p, const RGB &c) {
if(!bounds.contains(p)) return;
uint8_t _dmv = dither16_pattern[(p.x & 0b11) | ((p.y & 0b11) << 2)];

View File

@ -1,3 +1,7 @@
if(NOT TARGET motor)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/motor/motor.cmake)
endif()
add_library(pico_motor_shim INTERFACE)
target_include_directories(pico_motor_shim INTERFACE ${CMAKE_CURRENT_LIST_DIR})

View File

@ -1,3 +1,7 @@
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
add_library(pico_scroll INTERFACE)
set(PICO_SCROLL_SOURCES

View File

@ -1,3 +1,7 @@
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
add_library(pico_unicorn INTERFACE)
pico_generate_pio_header(pico_unicorn ${CMAKE_CURRENT_LIST_DIR}/pico_unicorn.pio)

View File

@ -2,7 +2,9 @@
#include "hardware/irq.h"
#include "common/pimoroni_common.hpp"
#ifndef NO_QSTR
#include "pico_unicorn.pio.h"
#endif
#include "pico_unicorn.hpp"
// pixel data is stored as a stream of bits delivered in the

View File

@ -0,0 +1,181 @@
#include <cstdint>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <optional>
#include <map>
#include "alright_fonts.hpp"
using namespace pretty_poly;
namespace alright_fonts {
/*
utility functions
*/
pretty_poly::rect_t measure_character(text_metrics_t &tm, uint16_t codepoint) {
if(tm.face.glyphs.count(codepoint) == 1) {
glyph_t glyph = tm.face.glyphs[codepoint];
return {0, 0, ((glyph.advance * tm.size) / 128), tm.size};
}
return {0, 0, 0, 0};
}
/*
render functions
*/
void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t<int> origin) {
if(tm.face.glyphs.count(codepoint) == 1) {
glyph_t glyph = tm.face.glyphs[codepoint];
// scale is a fixed point 16:16 value, our font data is already scaled to
// -128..127 so to get the pixel size we want we can just shift the
// users requested size up one bit
unsigned scale = tm.size << 9;
pretty_poly::draw_polygon<int8_t>(glyph.contours, origin, scale);
}
}
template<typename mat_t>
void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t<int> origin, mat_t transform) {
if(tm.face.glyphs.count(codepoint) == 1) {
glyph_t glyph = tm.face.glyphs[codepoint];
// scale is a fixed point 16:16 value, our font data is already scaled to
// -128..127 so to get the pixel size we want we can just shift the
// users requested size up one bit
unsigned scale = tm.size << 9;
std::vector<pretty_poly::contour_t<int8_t>> contours;
contours.reserve(glyph.contours.size());
unsigned int total_points = 0;
for(auto i = 0u; i < glyph.contours.size(); i++) {
total_points += glyph.contours[i].count;;
}
point_t<int8_t> *points = (point_t<int8_t> *)malloc(sizeof(point_t<int8_t>) * total_points);
for(auto i = 0u; i < glyph.contours.size(); i++) {
const unsigned int count = glyph.contours[i].count;
for(auto j = 0u; j < count; j++) {
point_t<float> point(glyph.contours[i].points[j].x, glyph.contours[i].points[j].y);
point *= transform;
points[j] = point_t<int8_t>(point.x, point.y);
}
contours.emplace_back(points, count);
points += count;
}
pretty_poly::draw_polygon<int8_t>(contours, origin, scale);
free(contours[0].points);
}
}
template void render_character<pretty_poly::mat3_t>(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t<int> origin, pretty_poly::mat3_t transform);
template void render_character<pretty_poly::mat2_t>(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t<int> origin, pretty_poly::mat2_t transform);
/*
load functions
*/
// big endian stream value helpers
uint16_t ru16(file_io &ifs) {uint8_t w[2]; ifs.read((char *)w, 2); return w[0] << 8 | w[1];}
int16_t rs16(file_io &ifs) {uint8_t w[2]; ifs.read((char *)w, 2); return w[0] << 8 | w[1];}
uint32_t ru32(file_io &ifs) {uint8_t dw[4]; ifs.read((char *)dw, 4); return dw[0] << 24 | dw[1] << 16 | dw[2] << 8 | dw[3];}
uint8_t ru8(file_io &ifs) {uint8_t w; ifs.read(&w, 1); return w;}
int8_t rs8(file_io &ifs) {int8_t w; ifs.read(&w, 1); return w;}
bool face_t::load(file_io &ifs) {
char marker[4];
ifs.read(marker, sizeof(marker));
// check header magic bytes are present
if(memcmp(marker, "af!?", 4) != 0) {
// doesn't start with magic marker
return false;
}
// number of glyphs embedded in font file
this->glyph_count = ru16(ifs);
// extract flags and ensure none set
this->flags = ru16(ifs);
if(this->flags != 0) {
// unknown flags set
return false;
}
// extract glyph dictionary
uint16_t glyph_entry_size = 9;
uint32_t contour_data_offset = 8 + this->glyph_count * glyph_entry_size;
for(auto i = 0; i < this->glyph_count; i++) {
glyph_t g;
g.codepoint = ru16(ifs);
g.bounds.x = rs8(ifs);
g.bounds.y = rs8(ifs);
g.bounds.w = ru8(ifs);
g.bounds.h = ru8(ifs);
g.advance = ru8(ifs);
if(ifs.fail()) {
// could not read glyph dictionary entry
return false;
}
// allocate space for the contour data and read it from the font file
uint16_t contour_data_length = ru16(ifs);
// remember where we are in the dictionary
int pos = ifs.tell();
// read contour data
ifs.seek(contour_data_offset);
while(true) {
// get number of points in contour
uint16_t count = ru16(ifs);
// if count is zero then this is the end of contour marker
if(count == 0) {
break;
}
// allocate space to store point data for contour and read
// from file
pretty_poly::point_t<int8_t> *points = new pretty_poly::point_t<int8_t>[count];
ifs.read((char *)points, count * 2);
g.contours.push_back({points, count});
}
// return back to position in dictionary
ifs.seek(pos);
contour_data_offset += contour_data_length;
if(ifs.fail()) {
// could not read glyph contour data
return false;
}
this->glyphs[g.codepoint] = g;
}
return true;
}
bool face_t::load(std::string_view path) {
file_io ifs(path);
if(ifs.fail()) {
// could not open file
return false;
}
return load(ifs);
}
}

View File

@ -0,0 +1,75 @@
#include <cstdint>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <optional>
#include <map>
#include "pretty_poly.hpp"
namespace alright_fonts {
struct glyph_t {
uint16_t codepoint;
pretty_poly::rect_t bounds;
uint8_t advance;
std::vector<pretty_poly::contour_t<int8_t>> contours;
};
struct face_t {
uint16_t glyph_count;
uint16_t flags;
std::map<uint16_t, glyph_t> glyphs;
face_t() {};
face_t(pretty_poly::file_io &ifs) {load(ifs);}
face_t(std::string_view path) {load(path);}
bool load(pretty_poly::file_io &ifs);
bool load(std::string_view path);
};
enum alignment_t {
left = 0,
center = 1,
right = 2,
justify = 4,
top = 8,
bottom = 16
};
struct text_metrics_t {
face_t face; // font to write in
int size; // text size in pixels
uint scroll; // vertical scroll offset
int line_height; // spacing between lines (%)
int letter_spacing; // spacing between characters
int word_spacing; // spacing between words
alignment_t align; // horizontal and vertical alignment
//optional<mat3_t> transform; // arbitrary transformation
pretty_poly::antialias_t antialiasing = pretty_poly::X4; // level of antialiasing to apply
void set_size(int s) {
size = s;
line_height = size;
letter_spacing = 0;
word_spacing = size / 2;
}
text_metrics_t() {};
};
/*
utility functions
*/
pretty_poly::rect_t measure_character(text_metrics_t &tm, uint16_t codepoint);
/*
render functions
*/
void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t<int> origin);
template<typename mat_t>
void render_character(text_metrics_t &tm, uint16_t codepoint, pretty_poly::point_t<int> origin, mat_t transform);
}

View File

@ -0,0 +1,9 @@
add_library(pico_vector
${CMAKE_CURRENT_LIST_DIR}/pico_vector.cpp
${CMAKE_CURRENT_LIST_DIR}/pretty_poly.cpp
${CMAKE_CURRENT_LIST_DIR}/alright_fonts.cpp
)
target_include_directories(pico_vector INTERFACE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(pico_vector pico_stdlib hardware_interp)

View File

@ -0,0 +1,192 @@
#include "pico_vector.hpp"
#include <vector>
namespace pimoroni {
void PicoVector::polygon(std::vector<pretty_poly::contour_t<picovector_point_type>> contours, Point origin, int scale) {
pretty_poly::settings::clip = {graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h};
pretty_poly::draw_polygon<picovector_point_type>(
contours,
pretty_poly::point_t<int>(origin.x, origin.y),
scale);
}
void PicoVector::rotate(std::vector<pretty_poly::contour_t<picovector_point_type>> &contours, Point origin, float angle) {
pretty_poly::point_t<picovector_point_type> t{(picovector_point_type)origin.x, (picovector_point_type)origin.y};
angle = (2 * (float)M_PI / 360.f) * angle;
pretty_poly::mat2_t r = pretty_poly::mat2_t::rotation(angle);
for(auto &contour : contours) {
for(auto i = 0u; i < contour.count; i++) {
contour.points[i] -= t;
contour.points[i] *= r;
contour.points[i] += t;
}
}
}
void PicoVector::translate(std::vector<pretty_poly::contour_t<picovector_point_type>> &contours, Point translation) {
pretty_poly::point_t<picovector_point_type> t{(picovector_point_type)translation.x, (picovector_point_type)translation.y};
for(auto &contour : contours) {
for(auto i = 0u; i < contour.count; i++) {
contour.points[i] += t;
}
}
}
void PicoVector::rotate(pretty_poly::contour_t<picovector_point_type> &contour, Point origin, float angle) {
pretty_poly::point_t<picovector_point_type> t{(picovector_point_type)origin.x, (picovector_point_type)origin.y};
angle = (2 * (float)M_PI / 360.f) * angle;
pretty_poly::mat2_t r = pretty_poly::mat2_t::rotation(angle);
for(auto i = 0u; i < contour.count; i++) {
contour.points[i] -= t;
contour.points[i] *= r;
contour.points[i] += t;
}
}
void PicoVector::translate(pretty_poly::contour_t<picovector_point_type> &contour, Point translation) {
pretty_poly::point_t<picovector_point_type> t{(picovector_point_type)translation.x, (picovector_point_type)translation.y};
for(auto i = 0u; i < contour.count; i++) {
contour.points[i] += t;
}
}
Point PicoVector::text(std::string_view text, Point origin) {
// Copy clipping bounds from the PicoGraphics instance
pretty_poly::settings::clip = {graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h};
// TODO: Normalize types somehow, so we're not converting?
pretty_poly::point_t<int> caret = pretty_poly::point_t<int>(origin.x, origin.y);
// Align text from the bottom left
caret.y += text_metrics.size;
int16_t space_width = alright_fonts::measure_character(text_metrics, ' ').w;
if (space_width == 0) {
space_width = text_metrics.word_spacing;
}
size_t i = 0;
while(i < text.length()) {
size_t next_space = text.find(' ', i + 1);
if(next_space == std::string::npos) {
next_space = text.length();
}
size_t next_linebreak = text.find('\n', i + 1);
if(next_linebreak == std::string::npos) {
next_linebreak = text.length();
}
size_t next_break = std::min(next_space, next_linebreak);
uint16_t word_width = 0;
for(size_t j = i; j < next_break; j++) {
word_width += alright_fonts::measure_character(text_metrics, text[j]).w;
word_width += text_metrics.letter_spacing;
}
if(caret.x != 0 && caret.x + word_width > graphics->clip.w) {
caret.x = origin.x;
caret.y += text_metrics.line_height;
}
for(size_t j = i; j < std::min(next_break + 1, text.length()); j++) {
if (text[j] == '\n') { // Linebreak
caret.x = origin.x;
caret.y += text_metrics.line_height;
} else if (text[j] == ' ') { // Space
caret.x += space_width;
} else {
alright_fonts::render_character(text_metrics, text[j], caret);
}
caret.x += alright_fonts::measure_character(text_metrics, text[j]).w;
caret.x += text_metrics.letter_spacing;
}
i = next_break + 1;
}
return Point(caret.x, caret.y);
}
Point PicoVector::text(std::string_view text, Point origin, float angle) {
// Copy clipping bounds from the PicoGraphics instance
pretty_poly::settings::clip = {graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h};
// TODO: Normalize types somehow, so we're not converting?
pretty_poly::point_t<float> caret(0, 0);
// Prepare a transformation matrix for character and offset rotation
angle = (2 * (float)M_PI / 360.f) * angle;
pretty_poly::mat2_t transform = pretty_poly::mat2_t::rotation(angle);
// Align text from the bottom left
caret.y += text_metrics.line_height;
caret *= transform;
pretty_poly::point_t<float> space;
pretty_poly::point_t<float> carriage_return(0, -text_metrics.line_height);
space.x = alright_fonts::measure_character(text_metrics, ' ').w;
if (space.x == 0) {
space.x = text_metrics.word_spacing;
}
space *= transform;
carriage_return *= transform;
const pretty_poly::point_t<float> initial_carriage_return = carriage_return;
size_t i = 0;
while(i < text.length()) {
size_t next_space = text.find(' ', i + 1);
if(next_space == std::string::npos) {
next_space = text.length();
}
size_t next_linebreak = text.find('\n', i + 1);
if(next_linebreak == std::string::npos) {
next_linebreak = text.length();
}
size_t next_break = std::min(next_space, next_linebreak);
uint16_t word_width = 0;
for(size_t j = i; j < next_break; j++) {
word_width += alright_fonts::measure_character(text_metrics, text[j]).w;
word_width += text_metrics.letter_spacing;
}
if(caret.x != 0 && caret.x + word_width > graphics->clip.w) {
caret -= carriage_return;
carriage_return = initial_carriage_return;
}
for(size_t j = i; j < std::min(next_break + 1, text.length()); j++) {
if (text[j] == '\n') { // Linebreak
caret -= carriage_return;
carriage_return = initial_carriage_return;
} else if (text[j] == ' ') { // Space
caret += space;
carriage_return += space;
} else {
alright_fonts::render_character(text_metrics, text[j], pretty_poly::point_t<int>(origin.x + caret.x, origin.y + caret.y), transform);
}
pretty_poly::point_t<float> advance(
alright_fonts::measure_character(text_metrics, text[j]).w + text_metrics.letter_spacing,
0
);
advance *= transform;
caret += advance;
carriage_return += advance;
}
i = next_break + 1;
}
return Point(caret.x, caret.y);
}
}

View File

@ -0,0 +1,87 @@
#include "pretty_poly.hpp"
#include "alright_fonts.hpp"
#include "pico_graphics.hpp"
namespace pimoroni {
// Integer point types cause compound error in transformations
typedef float picovector_point_type;
class PicoVector {
private:
PicoGraphics *graphics;
alright_fonts::text_metrics_t text_metrics;
const uint8_t alpha_map[4] {0, 128, 192, 255};
public:
PicoVector(PicoGraphics *graphics, void *mem = nullptr) : graphics(graphics) {
pretty_poly::init(mem);
set_options([this](const pretty_poly::tile_t &tile) -> void {
uint8_t *tile_data = tile.data;
if(this->graphics->supports_alpha_blend() && pretty_poly::settings::antialias != pretty_poly::NONE) {
if (this->graphics->render_pico_vector_tile({tile.bounds.x, tile.bounds.y, tile.bounds.w, tile.bounds.h},
tile.data,
tile.stride,
(uint8_t)pretty_poly::settings::antialias)) {
return;
}
for(auto y = 0; y < tile.bounds.h; y++) {
for(auto x = 0; x < tile.bounds.w; x++) {
uint8_t alpha = *tile_data++;
if (alpha >= 4) {
this->graphics->set_pixel({x + tile.bounds.x, y + tile.bounds.y});
} else if (alpha > 0) {
alpha = alpha_map[alpha];
this->graphics->set_pixel_alpha({x + tile.bounds.x, y + tile.bounds.y}, alpha);
}
}
tile_data += tile.stride - tile.bounds.w;
}
} else {
for(auto y = 0; y < tile.bounds.h; y++) {
for(auto x = 0; x < tile.bounds.w; x++) {
uint8_t alpha = *tile_data++;
if (alpha) {
this->graphics->set_pixel({x + tile.bounds.x, y + tile.bounds.y});
}
}
tile_data += tile.stride - tile.bounds.w;
}
}
}, graphics->supports_alpha_blend() ? pretty_poly::X4 : pretty_poly::NONE, {graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h});
}
void set_antialiasing(pretty_poly::antialias_t antialias) {
set_options(pretty_poly::settings::callback, antialias, pretty_poly::settings::clip);
}
void set_font_size(unsigned int font_size) {
text_metrics.set_size(font_size);
}
bool set_font(std::string_view font_path, unsigned int font_size) {
bool result = text_metrics.face.load(font_path);
set_font_size(font_size);
return result;
}
void rotate(std::vector<pretty_poly::contour_t<picovector_point_type>> &contours, Point origin, float angle);
void translate(std::vector<pretty_poly::contour_t<picovector_point_type>> &contours, Point translation);
void rotate(pretty_poly::contour_t<picovector_point_type> &contour, Point origin, float angle);
void translate(pretty_poly::contour_t<picovector_point_type> &contour, Point translation);
Point text(std::string_view text, Point origin);
Point text(std::string_view text, Point origin, float angle);
void polygon(std::vector<pretty_poly::contour_t<picovector_point_type>> contours, Point origin = Point(0, 0), int scale=65536);
static constexpr size_t pretty_poly_buffer_size() {
return pretty_poly::buffer_size();
};
};
}

View File

@ -0,0 +1,339 @@
#include <cstdint>
#include <algorithm>
#include <optional>
#include <cstring>
#include <new>
#include <filesystem>
#include <fstream>
#include "pretty_poly.hpp"
#include "hardware/interp.h"
#ifdef PP_DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
namespace pretty_poly {
uint8_t *tile_buffer;
int (*nodes)[32];
unsigned *node_counts;
// default tile bounds to X1 antialiasing
rect_t tile_bounds(0, 0, tile_buffer_size / node_buffer_size, node_buffer_size);
// user settings
namespace settings {
rect_t clip(0, 0, 320, 240);
tile_callback_t callback;
antialias_t antialias = antialias_t::NONE;
}
void init(void *memory) {
uintptr_t m = (uintptr_t)memory;
tile_buffer = new(memory) uint8_t[tile_buffer_size];
node_counts = new((void *)(m + tile_buffer_size)) unsigned[node_buffer_size];
nodes = new((void *)(m + tile_buffer_size + (node_buffer_size * sizeof(unsigned)))) int[node_buffer_size][32];
}
void set_options(tile_callback_t callback, antialias_t antialias, rect_t clip) {
settings::callback = callback;
settings::antialias = antialias;
settings::clip = clip;
// recalculate the tile size for rendering based on antialiasing level
int tile_height = node_buffer_size >> antialias;
tile_bounds = rect_t(0, 0, tile_buffer_size / tile_height, tile_height);
}
// dy step (returns 1, 0, or -1 if the supplied value is > 0, == 0, < 0)
inline constexpr int sign(int v) {
// assumes 32-bit int/unsigned
return ((unsigned)-v >> 31) - ((unsigned)v >> 31);
}
// write out the tile bits
void debug_tile(const tile_t &tile) {
debug(" - tile %d, %d (%d x %d)\n", tile.bounds.x, tile.bounds.y, tile.bounds.w, tile.bounds.h);
for(auto y = 0; y < tile.bounds.h; y++) {
debug("[%3d]: ", y);
for(auto x = 0; x < tile.bounds.w; x++) {
debug("%d", tile.get_value(x, y));
}
debug("\n");
}
debug("-----------------------\n");
}
void add_line_segment_to_nodes(const point_t<int> &start, const point_t<int> &end) {
// swap endpoints if line "pointing up", we do this because we
// alway skip the last scanline (so that polygons can but cleanly
// up against each other without overlap)
int sx = start.x, sy = start.y, ex = end.x, ey = end.y;
if(ey < sy) {
std::swap(sy, ey);
std::swap(sx, ex);
}
// Early out if line is completely outside the tile, or has no lines
if (ey < 0 || sy >= (int)node_buffer_size || sy == ey) return;
debug(" + line segment from %d, %d to %d, %d\n", sx, sy, ex, ey);
// Determine how many in-bounds lines to render
int y = std::max(0, sy);
int count = std::min((int)node_buffer_size, ey) - y;
// Handle cases where x is completely off to one side or other
if (std::max(sx, ex) <= 0) {
while (count--) {
nodes[y][node_counts[y]++] = 0;
++y;
}
return;
}
const int full_tile_width = (tile_bounds.w << settings::antialias);
if (std::min(sx, ex) >= full_tile_width) {
while (count--) {
nodes[y][node_counts[y]++] = full_tile_width;
++y;
}
return;
}
// Normal case
int x = sx;
int e = 0;
const int xinc = sign(ex - sx);
const int einc = abs(ex - sx) + 1;
const int dy = ey - sy;
// If sy < 0 jump to the start, note this does use a divide
// but potentially saves many wasted loops below, so is likely worth it.
if (sy < 0) {
e = einc * -sy;
int xjump = e / dy;
e -= dy * xjump;
x += xinc * xjump;
}
interp1->base[1] = full_tile_width;
interp1->accum[0] = x;
// loop over scanlines
while(count--) {
// consume accumulated error
while(e > dy) {e -= dy; interp1->add_raw[0] = xinc;}
// clamp node x value to tile bounds
const int nx = interp1->peek[0];
debug(" + adding node at %d, %d\n", x, y);
// add node to node list
nodes[y][node_counts[y]++] = nx;
// step to next scanline and accumulate error
y++;
e += einc;
}
}
template<typename T>
void build_nodes(const contour_t<T> &contour, const tile_t &tile, point_t<int> origin, int scale) {
int ox = (origin.x - tile.bounds.x) << settings::antialias;
int oy = (origin.y - tile.bounds.y) << settings::antialias;
// start with the last point to close the loop
point_t<int> last(
(((int(contour.points[contour.count - 1].x) * scale) << settings::antialias) / 65536) + ox,
(((int(contour.points[contour.count - 1].y) * scale) << settings::antialias) / 65536) + oy
);
for(auto i = 0u; i < contour.count; i++) {
point_t<int> point(
(((int(contour.points[i].x) * scale) << settings::antialias) / 65536) + ox,
(((int(contour.points[i].y) * scale) << settings::antialias) / 65536) + oy
);
add_line_segment_to_nodes(last, point);
last = point;
}
}
void render_nodes(const tile_t &tile, rect_t &bounds) {
int maxy = -1;
bounds.y = 0;
bounds.x = tile.bounds.w;
int maxx = 0;
int anitialias_mask = (1 << settings::antialias) - 1;
for(auto y = 0; y < (int)node_buffer_size; y++) {
if(node_counts[y] == 0) {
if (y == bounds.y) ++bounds.y;
continue;
}
std::sort(&nodes[y][0], &nodes[y][0] + node_counts[y]);
uint8_t* row_data = &tile.data[(y >> settings::antialias) * tile.stride];
bool rendered_any = false;
for(auto i = 0u; i < node_counts[y]; i += 2) {
int sx = nodes[y][i + 0];
int ex = nodes[y][i + 1];
if(sx == ex) {
continue;
}
rendered_any = true;
maxx = std::max((ex - 1) >> settings::antialias, maxx);
debug(" - render span at %d from %d to %d\n", y, sx, ex);
if (settings::antialias) {
int ax = sx >> settings::antialias;
const int aex = ex >> settings::antialias;
bounds.x = std::min(ax, bounds.x);
if (ax == aex) {
row_data[ax] += ex - sx;
continue;
}
row_data[ax] += (1 << settings::antialias) - (sx & anitialias_mask);
for(ax++; ax < aex; ax++) {
row_data[ax] += (1 << settings::antialias);
}
// This might add 0 to the byte after the end of the row, we pad the tile data
// by 1 byte to ensure that is OK
row_data[ax] += ex & anitialias_mask;
}
else {
bounds.x = std::min(sx, bounds.x);
for(int x = sx; x < ex; x++) {
row_data[x]++;
}
}
}
if (rendered_any) {
debug(" - rendered line %d\n", y);
maxy = y;
}
else if (y == bounds.y) {
debug(" - render nothing on line %d\n", y);
++bounds.y;
}
}
bounds.y >>= settings::antialias;
maxy >>= settings::antialias;
bounds.w = (maxx >= bounds.x) ? maxx + 1 - bounds.x : 0;
bounds.h = (maxy >= bounds.y) ? maxy + 1 - bounds.y : 0;
debug(" - rendered tile bounds %d, %d (%d x %d)\n", bounds.x, bounds.y, bounds.w, bounds.h);
}
template<typename T>
void draw_polygon(T *points, unsigned count) {
std::vector<contour_t<T>> contours;
contour_t<T> c(points, count);
contours.push_back(c);
draw_polygon<T>(contours);
}
template<typename T>
void draw_polygon(const std::vector<contour_t<T>>& contours, point_t<int> origin, int scale) {
debug("> draw polygon with %lu contours\n", contours.size());
if(contours.size() == 0) {
return;
}
// determine extreme bounds
rect_t polygon_bounds = contours[0].bounds();
for(auto &contour : contours) {
polygon_bounds = polygon_bounds.merge(contour.bounds());
}
polygon_bounds.x = ((polygon_bounds.x * scale) / 65536) + origin.x;
polygon_bounds.y = ((polygon_bounds.y * scale) / 65536) + origin.y;
polygon_bounds.w = ((polygon_bounds.w * scale) / 65536);
polygon_bounds.h = ((polygon_bounds.h * scale) / 65536);
debug(" - bounds %d, %d (%d x %d)\n", polygon_bounds.x, polygon_bounds.y, polygon_bounds.w, polygon_bounds.h);
debug(" - clip %d, %d (%d x %d)\n", settings::clip.x, settings::clip.y, settings::clip.w, settings::clip.h);
interp_hw_save_t interp1_save;
interp_save(interp1, &interp1_save);
interp_config cfg = interp_default_config();
interp_config_set_clamp(&cfg, true);
interp_config_set_signed(&cfg, true);
interp_set_config(interp1, 0, &cfg);
interp1->base[0] = 0;
//memset(nodes, 0, node_buffer_size * sizeof(unsigned) * 32);
// iterate over tiles
debug(" - processing tiles\n");
for(auto y = polygon_bounds.y; y < polygon_bounds.y + polygon_bounds.h; y += tile_bounds.h) {
for(auto x = polygon_bounds.x; x < polygon_bounds.x + polygon_bounds.w; x += tile_bounds.w) {
tile_t tile;
tile.bounds = rect_t(x, y, tile_bounds.w, tile_bounds.h).intersection(settings::clip);
tile.stride = tile_bounds.w;
tile.data = tile_buffer;
debug(" : %d, %d (%d x %d)\n", tile.bounds.x, tile.bounds.y, tile.bounds.w, tile.bounds.h);
// if no intersection then skip tile
if(tile.bounds.empty()) {
debug(" : empty when clipped, skipping\n");
continue;
}
// clear existing tile data and nodes
memset(node_counts, 0, node_buffer_size * sizeof(unsigned));
memset(tile.data, 0, tile_buffer_size);
// build the nodes for each contour
for(const contour_t<T> &contour : contours) {
debug(" : build nodes for contour\n");
build_nodes(contour, tile, origin, scale);
}
debug(" : render the tile\n");
// render the tile
rect_t bounds;
render_nodes(tile, bounds);
if (bounds.empty()) {
continue;
}
tile.data += bounds.x + tile.stride * bounds.y;
tile.bounds.x += bounds.x;
tile.bounds.y += bounds.y;
tile.bounds.w = bounds.w;
tile.bounds.h = bounds.h;
settings::callback(tile);
}
}
interp_restore(interp1, &interp1_save);
}
}
template void pretty_poly::draw_polygon<int>(const std::vector<contour_t<int>>& contours, point_t<int> origin, int scale);
template void pretty_poly::draw_polygon<float>(const std::vector<contour_t<float>>& contours, point_t<int> origin, int scale);
template void pretty_poly::draw_polygon<uint8_t>(const std::vector<contour_t<uint8_t>>& contours, point_t<int> origin, int scale);
template void pretty_poly::draw_polygon<int8_t>(const std::vector<contour_t<int8_t>>& contours, point_t<int> origin, int scale);

View File

@ -0,0 +1,73 @@
#pragma once
#include <cstdint>
#include <algorithm>
#include <optional>
#include <cstring>
#include <new>
#include <filesystem>
#include <fstream>
#include <functional>
#include "pretty_poly_types.hpp"
namespace pretty_poly {
class file_io {
private:
void *state;
size_t filesize = 0;
public:
file_io(std::string_view path);
~file_io();
size_t seek(size_t pos);
size_t read(void *buf, size_t len);
size_t tell();
bool fail();
};
// buffer that each tile is rendered into before callback
constexpr unsigned tile_buffer_size = 1024;
// polygon node buffer handles at most 16 line intersections per scanline
// is this enough for cjk/emoji? (requires a 2kB buffer)
constexpr unsigned node_buffer_size = 32;
typedef std::function<void(const tile_t &tile)> tile_callback_t;
// user settings
namespace settings {
extern rect_t clip;
extern tile_callback_t callback;
extern antialias_t antialias;
}
constexpr size_t buffer_size() {
return tile_buffer_size + (node_buffer_size * sizeof(unsigned)) + (node_buffer_size * 32 * sizeof(int));
}
constexpr size_t buffer_size();
void init(void *memory);
void set_options(tile_callback_t callback, antialias_t antialias, rect_t clip);
// dy step (returns 1, 0, or -1 if the supplied value is > 0, == 0, < 0)
inline constexpr int sign(int v);
// write out the tile bits
void debug_tile(const tile_t &tile);
void add_line_segment_to_nodes(const point_t<int> &start, const point_t<int> &end);
template<typename T>
void build_nodes(const contour_t<T> &contour, const tile_t &tile, point_t<int> origin = point_t<int>(0, 0), int scale = 65536);
void render_nodes(const tile_t &tile, rect_t &bounds);
template<typename T>
void draw_polygon(T *points, unsigned count);
template<typename T>
void draw_polygon(const std::vector<contour_t<T>>& contours, point_t<int> origin = point_t<int>(0, 0), int scale = 65536);
}

View File

@ -0,0 +1,162 @@
#pragma once
#include <cstdint>
#include <math.h>
#include <vector>
#ifdef PP_DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
namespace pretty_poly {
enum antialias_t {NONE = 0, X4 = 1, X16 = 2};
// 3x3 matrix for coordinate transformations
struct mat3_t {
float v00 = 0.0f, v10 = 0.0f, v20 = 0.0f, v01 = 0.0f, v11 = 0.0f, v21 = 0.0f, v02 = 0.0f, v12 = 0.0f, v22 = 0.0f;
mat3_t() = default;
mat3_t(const mat3_t &m) = default;
inline mat3_t& operator*= (const mat3_t &m) {
float r00 = this->v00 * m.v00 + this->v01 * m.v10 + this->v02 * m.v20;
float r01 = this->v00 * m.v01 + this->v01 * m.v11 + this->v02 * m.v21;
float r02 = this->v00 * m.v02 + this->v01 * m.v12 + this->v02 * m.v22;
float r10 = this->v10 * m.v00 + this->v11 * m.v10 + this->v12 * m.v20;
float r11 = this->v10 * m.v01 + this->v11 * m.v11 + this->v12 * m.v21;
float r12 = this->v10 * m.v02 + this->v11 * m.v12 + this->v12 * m.v22;
float r20 = this->v20 * m.v00 + this->v21 * m.v10 + this->v22 * m.v20;
float r21 = this->v20 * m.v01 + this->v21 * m.v11 + this->v22 * m.v21;
float r22 = this->v20 * m.v02 + this->v21 * m.v12 + this->v22 * m.v22;
this->v00 = r00; this->v01 = r01; this->v02 = r02;
this->v10 = r10; this->v11 = r11; this->v12 = r12;
this->v20 = r20; this->v21 = r21; this->v22 = r22;
return *this;
}
static mat3_t identity() {mat3_t m; m.v00 = m.v11 = m.v22 = 1.0f; return m;}
static mat3_t rotation(float a) {
float c = cosf(a), s = sinf(a); mat3_t r = mat3_t::identity();
r.v00 = c; r.v01 = -s; r.v10 = s; r.v11 = c; return r;}
static mat3_t translation(float x, float y) {
mat3_t r = mat3_t::identity(); r.v02 = x; r.v12 = y; return r;}
static mat3_t scale(float x, float y) {
mat3_t r = mat3_t::identity(); r.v00 = x; r.v11 = y; return r;}
};
// 2x2 matrix for rotations and scales
struct mat2_t {
float v00 = 0.0f, v10 = 0.0f, v01 = 0.0f, v11 = 0.0f;
mat2_t() = default;
mat2_t(const mat2_t &m) = default;
inline mat2_t& operator*= (const mat2_t &m) {
float r00 = this->v00 * m.v00 + this->v01 * m.v10;
float r01 = this->v00 * m.v01 + this->v01 * m.v11;
float r10 = this->v10 * m.v00 + this->v11 * m.v10;
float r11 = this->v10 * m.v01 + this->v11 * m.v11;
this->v00 = r00; this->v01 = r01;
this->v10 = r10; this->v11 = r11;
return *this;
}
static mat2_t identity() {mat2_t m; m.v00 = m.v11 = 1.0f; return m;}
static mat2_t rotation(float a) {
float c = cosf(a), s = sinf(a); mat2_t r;
r.v00 = c; r.v01 = -s; r.v10 = s; r.v11 = c; return r;}
static mat2_t scale(float x, float y) {
mat2_t r; r.v00 = x; r.v11 = y; return r;}
};
// point type for contour points
template<typename T = int>
struct __attribute__ ((packed)) point_t {
T x, y;
point_t(T x, T y) : x(x), y(y) {}
point_t() : x(0), y(0) {}
inline point_t& operator-= (const point_t &a) {x -= a.x; y -= a.y; return *this;}
inline point_t& operator+= (const point_t &a) {x += a.x; y += a.y; return *this;}
inline point_t& operator*= (const float a) {x *= a; y *= a; return *this;}
inline point_t& operator*= (const mat2_t &a) {this->transform(a); return *this;}
inline point_t& operator*= (const mat3_t &a) {this->transform(a); return *this;}
inline point_t& operator/= (const float a) {x /= a; y /= a; return *this;}
inline point_t& operator/= (const point_t &a) {x /= a.x; y /= a.y; return *this;}
void transform(const mat3_t &m) {
float tx = x, ty = y;
this->x = (m.v00 * tx + m.v01 * ty + m.v02);
this->y = (m.v10 * tx + m.v11 * ty + m.v12);
}
void transform(const mat2_t &m) {
float tx = x, ty = y;
this->x = (m.v00 * tx + m.v01 * ty);
this->y = (m.v10 * tx + m.v11 * ty);
}
};
template<typename T> inline point_t<T> operator- (point_t<T> lhs, const point_t<T> &rhs) { lhs -= rhs; return lhs; }
template<typename T> inline point_t<T> operator- (const point_t<T> &rhs) { return point_t<T>(-rhs.x, -rhs.y); }
template<typename T> inline point_t<T> operator+ (point_t<T> lhs, const point_t<T> &rhs) { lhs += rhs; return lhs; }
template<typename T> inline point_t<T> operator* (point_t<T> lhs, const float rhs) { lhs *= rhs; return lhs; }
template<typename T> inline point_t<T> operator* (point_t<T> lhs, const point_t<T> &rhs) { lhs *= rhs; return lhs; }
template<typename T> inline point_t<T> operator* (point_t<T> lhs, const mat3_t &rhs) { lhs *= rhs; return lhs; }
template<typename T> inline point_t<T> operator/ (point_t<T> lhs, const float rhs) { lhs /= rhs; return lhs; }
template<typename T> inline point_t<T> operator/ (point_t<T> lhs, const point_t<T> &rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; }
// rect type for bounds and clipping rectangles
struct rect_t {
int x, y, w, h;
rect_t() : x(0), y(0), w(0), h(0) {}
rect_t(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {}
bool empty() const {return this->w == 0 || this->h == 0;}
rect_t intersection(const rect_t &c) {
return rect_t(std::max(this->x, c.x), std::max(this->y, c.y),
std::max(0, std::min(this->x + this->w, c.x + c.w) - std::max(this->x, c.x)),
std::max(0, std::min(this->y + this->h, c.y + c.h) - std::max(this->y, c.y)));
}
rect_t merge(const rect_t &c) {
return rect_t(std::min(this->x, c.x), std::min(this->y, c.y),
std::max(this->x + this->w, c.x + c.w) - std::min(this->x, c.x),
std::max(this->y + this->h, c.y + c.h) - std::min(this->y, c.y));
}
};
struct tile_t {
rect_t bounds;
unsigned stride;
uint8_t *data;
tile_t() {};
inline int get_value(int x, int y) const {
return this->data[x + y * this->stride];
}
};
template<typename T>
struct contour_t {
point_t<T> *points;
unsigned count;
contour_t() {}
contour_t(const std::vector<point_t<T>>& v) : points(v.data()), count(v.size()) {};
contour_t(point_t<T> *points, unsigned count) : points(points), count(count) {};
// TODO: Make this work, it's so much nicer to use auto point : contour
//point_t<T> *begin() const { return points; };
//point_t<T> *end() const { return points + count * sizeof(point_t<T>); };
rect_t bounds() const {
T minx = this->points[0].x, maxx = minx;
T miny = this->points[0].y, maxy = miny;
for(auto i = 1u; i < this->count; i++) {
minx = std::min(minx, this->points[i].x);
miny = std::min(miny, this->points[i].y);
maxx = std::max(maxx, this->points[i].x);
maxy = std::max(maxy, this->points[i].y);
}
return rect_t(minx, miny, maxx - minx, maxy - miny);
}
};
}

View File

@ -1,4 +1,7 @@
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/esp32spi/esp32spi.cmake)
if(NOT TARGET esp32spi)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/esp32spi/esp32spi.cmake)
endif()
add_library(pico_wireless INTERFACE)
target_sources(pico_wireless INTERFACE

View File

@ -1,3 +1,7 @@
if(NOT TARGET plasma)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/plasma/plasma.cmake)
endif()
add_library(plasma2040 INTERFACE)
target_include_directories(plasma2040 INTERFACE ${CMAKE_CURRENT_LIST_DIR})

View File

@ -1,3 +1,7 @@
if(NOT TARGET plasma)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/plasma/plasma.cmake)
endif()
add_library(plasma_stick INTERFACE)
target_include_directories(plasma_stick INTERFACE ${CMAKE_CURRENT_LIST_DIR})

View File

@ -1,3 +1,15 @@
if(NOT TARGET plasma)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/plasma/plasma.cmake)
endif()
if(NOT TARGET servo)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/servo/servo.cmake)
endif()
if(NOT TARGET servo_cluster)
include(${CMAKE_CURRENT_LIST_DIR}/../../drivers/servo/servo_cluster.cmake)
endif()
add_library(servo2040 INTERFACE)
target_include_directories(servo2040 INTERFACE ${CMAKE_CURRENT_LIST_DIR})

View File

@ -30,6 +30,10 @@ namespace servo {
const uint LED_DATA = 18;
const uint NUM_LEDS = 6;
const uint I2C_INT = 19;
const uint I2C_SDA = 20;
const uint I2C_SCL = 21;
const uint USER_SW = 23;
const uint ADC_ADDR_0 = 22;

View File

@ -1,3 +1,7 @@
if(NOT TARGET pico_graphics)
include(${CMAKE_CURRENT_LIST_DIR}/../pico_graphics/pico_graphics.cmake)
endif()
add_library(stellar_unicorn INTERFACE)
pico_generate_pio_header(stellar_unicorn ${CMAKE_CURRENT_LIST_DIR}/stellar_unicorn.pio)

View File

@ -6,8 +6,10 @@
#include "hardware/clocks.h"
#ifndef NO_QSTR
#include "stellar_unicorn.pio.h"
#include "audio_i2s.pio.h"
#endif
#include "stellar_unicorn.hpp"
@ -483,11 +485,14 @@ namespace pimoroni {
void StellarUnicorn::set_brightness(float value) {
value = value < 0.0f ? 0.0f : value;
value = value > 1.0f ? 1.0f : value;
// Max brightness is - in fact - 256 since it's applied with:
// result = (channel * brightness) >> 8
// eg: (255 * 256) >> 8 == 255
this->brightness = floor(value * 256.0f);
}
float StellarUnicorn::get_brightness() {
return this->brightness / 255.0f;
return this->brightness / 256.0f;
}
void StellarUnicorn::adjust_brightness(float delta) {

View File

@ -1,5 +1,6 @@
# cmake file for Pimoroni Enviro with Raspberry Pi Pico W
set(MICROPY_BOARD PICO_W)
set(MICROPY_BOARD RPI_PICO_W)
set(PICO_BOARD "pico_w")
# The C malloc is needed by cyw43-driver Bluetooth and Pimoroni Pico modules
set(MICROPY_C_HEAP_SIZE 4096)

View File

@ -5,6 +5,9 @@ require("bundle-networking")
require("urllib.urequest")
require("umqtt.simple")
# SD Card
require("sdcard")
# Bluetooth
require("aioble")

View File

@ -1,5 +1,6 @@
# cmake file for Pimoroni Inky with Raspberry Pi Pico W
set(MICROPY_BOARD PICO_W)
set(MICROPY_BOARD RPI_PICO_W)
set(PICO_BOARD "pico_w")
# The C malloc is needed by cyw43-driver Bluetooth and Pimoroni Pico modules
set(MICROPY_C_HEAP_SIZE 4096)

View File

@ -1,4 +1,5 @@
# cmake file for Raspberry Pi Pico
set(PICO_BOARD "pico")
# Board specific version of the frozen manifest
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)

View File

@ -2,6 +2,9 @@ include("$(PORT_DIR)/boards/manifest.py")
require("bundle-networking")
# SD Card
require("sdcard")
# Bluetooth
require("aioble")

View File

@ -1,4 +1,5 @@
# cmake file for Raspberry Pi Pico W
set(PICO_BOARD "pico_w")
# The C malloc is needed by cyw43-driver Bluetooth and Pimoroni Pico modules
set(MICROPY_C_HEAP_SIZE 4096)

View File

@ -7,4 +7,6 @@ if [[ -f "$FIXUP_DIR/$BOARD/pico_sdk.patch" ]]; then
echo "Applying pico_sdk.patch"
cd $MPY_DIR/lib/pico-sdk
git apply "$FIXUP_DIR/$BOARD/pico_sdk.patch"
else
echo "Skipping patch. $FIXUP_DIR/$BOARD/pico_sdk.patch not found!"
fi

View File

@ -1,104 +1,3 @@
# Badger 2040 Examples <!-- omit in toc -->
:warning: This code has been deprecated in favour of a dedicated Badger 2040 project: https://github.com/pimoroni/badger2040
- [Function Examples](#function-examples)
- [Battery](#battery)
- [Button Test](#button-test)
- [LED](#led)
- [Pin interrupt](#pin-interrupt)
- [Application Examples](#application-examples)
- [Badge](#badge)
- [Checklist](#checklist)
- [Clock](#clock)
- [E-Book](#e-book)
- [Fonts](#fonts)
- [Image](#image)
- [QR gen](#qr-gen)
- [Launcher](#launcher)
- [Conway](#conway)
## Function Examples
### Battery
[battery.py](battery.py)
An example of how to read the battery voltage and display a battery level indicator.
### Button Test
[button_test.py](button_test.py)
An example of how to read Badger2040's buttons and display a unique message for each.
### LED
[led.py](led.py)
Blinks Badger's LED on and off.
### Pin interrupt
[pin_interrupt.py](pin_interrupt.py)
An example of drawing text and graphics and using the buttons.
## Application Examples
### Badge
[badge.py](badge.py)
Create your own name badge! This application looks for two files on your MicroPython drive:
* `badge.txt` - A text file containing 6 lines, corresponding to the 6 different pieces of text on the badge
* `badge-image.bin` - A 104x128px 1-bit colour depth image to display alongside the text. You can use `examples/badger2040/image_converter/convert.py` to convert them:
```shell
python3 convert.py --binary --resize image_file_1.png image_file_2.png image_file_3.png
```
### Checklist
[list.py](list.py)
A checklist application, letting you navigate through items and tick each of them off.
* `checklist.txt` - A text file containing the titles of items for the list.
### Clock
[clock.py](clock.py)
A simple clock showing the time and date, that uses the E Ink's fast speed to update every second.
### E-Book
[ebook.py](ebook.py)
A mini text file e-reader. Comes pre-loaded with an excerpt of The Wind In the Willows.
### Fonts
[fonts.py](fonts.py)
A demonstration of the various fonts that can be used in your programs.
### Image
[image.py](image.py)
An image gallery. Displays and lets you cycle through any images stored within the MicroPython device's `/images` directory. Images must be 296x128 pixels with 1-bit colour depth. You can use `examples/badger2040/image_converter/convert.py` to convert them:
```shell
python3 convert.py --binary --resize image_file_1.png image_file_2.png image_file_3.png
```
### QR gen
[qrgen.py](qrgen.py)
Displays and lets you cycle through multiple QR codes, with configuration stored in text files within the MicroPython device's `/qrcodes` directory.
- `/qrcodes/qrcode.txt` - A text file containing 9 lines. The first line should be a URL which will be converted into and displayed as a QR code. Up to 8 more lines of information can be added, which will be shown as plain text to the right of the QR code.
- `/qrcodes/*.txt` - additional text files can be created using the same format. All text files can be cycled through.
### Launcher
[launcher.py](launcher.py)
A launcher-style application, providing a menu of other applications that can be loaded, as well as information such as battery level.
### Conway
[conway.py](conway.py)
Conway's classic Game of Life, implemented on the Badger. Note: this application is *not* linked from the Launcher by default - it can be run directly using Thonny or your MicroPython editor of choice, or you can modify the Launcher to add it (you'll want to update `launchericons.png` as well)

Some files were not shown because too many files have changed in this diff Show More