Skip to content

Commit

Permalink
Support for 5v level-shifter on Adafruit and Pimoroni boards (#8)
Browse files Browse the repository at this point in the history
* Add GA script for Adafruit and Pimoroni boards

Build firmware automatically. These boards have a built-in level shifter.

* Update README.md

* Update README.md

* Add Adafruit ItsyBitsy rp2040
  • Loading branch information
awawa-dev committed Jul 27, 2023
1 parent fae32e1 commit d35938d
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 14 deletions.
89 changes: 87 additions & 2 deletions .github/workflows/push-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,99 @@ jobs:
if: (startsWith(github.event.ref, 'refs/tags') != true)
with:
path: |
firmwares/*.uf2
firmware/*.uf2
- uses: actions/upload-artifact@v3
name: Upload artifacts (release)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
path: |
firmwares/*.uf2
firmware/*.uf2
- name: Build packages for Adafruit Feather RP2040 Scorpio (release-only)
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: |
cd build
rm *.*
rm ../firmware/*
echo "Neopixel is using GPIO16(OUTPUT_DATA_PIN) on output 0." > ../firmware/Firmwares_for_Adafruit_Feather_RP2040_Scorpio.txt
echo "SPI is using spi0 interface pins: GPIO19(OUTPUT_SPI_DATA_PIN) and GPIO18(OUTPUT_SPI_CLOCK_PIN) on output 3 and 2 respectively." >> ../firmware/Firmwares_for_Adafruit_Feather_RP2040_Scorpio.txt
cmake -DOVERRIDE_DATA_PIN=16 -DOVERRIDE_SPI_DATA_PIN=19 -DOVERRIDE_SPI_CLOCK_PIN=18 -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
zip -j ../firmware/Adafruit_Feather_RP2040_Scorpio.zip ../firmware/*
- uses: actions/upload-artifact@v3
name: Upload artifacts (release Adafruit_Feather)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
path: |
firmware/*.zip
- name: Build packages for Adafruit ItsyBitsy RP2040 (release-only)
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: |
cd build
rm *.*
rm ../firmware/*
echo "Neopixel is using GPIO14(OUTPUT_DATA_PIN) on output 5." > ../firmware/Firmwares_for_Adafruit_ItsyBitsy_2040.txt
cmake -DOVERRIDE_DATA_PIN=14 -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
rm ../firmware/*_Spi.uf2
zip -j ../firmware/Adafruit_ItsyBitsy_2040.zip ../firmware/*
- uses: actions/upload-artifact@v3
name: Upload artifacts (release Adafruit_ItsyBitsy)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
path: |
firmware/*.zip
- name: Build packages for Pimoroni Plasma Stick 2040 W (release-only)
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: |
cd build
rm *.*
rm ../firmware/*
echo "Neopixel is using GPIO15(OUTPUT_DATA_PIN) on output PIXELS." > ../firmware/Firmwares_for_Pimoroni_Plasma_Stick_2040_W.txt
cmake -DOVERRIDE_DATA_PIN=15 -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
rm ../firmware/*_Spi.uf2
zip -j ../firmware/Pimoroni_Plasma_Stick_2040_W.zip ../firmware/*
- uses: actions/upload-artifact@v3
name: Upload artifacts (release Pimoroni_Plasma_Stick_W)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
path: |
firmware/*.zip
- name: Build packages for Pimoroni Plasma 2040 (release-only)
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: |
cd build
rm *.*
rm ../firmware/*
echo "Neopixel is using GPIO15(OUTPUT_DATA_PIN) on output DA." > ../firmware/Firmwares_for_Pimoroni_Plasma_2040.txt
echo "SPI is using spi1 interface pins: GPIO15(OUTPUT_SPI_DATA_PIN) and GPIO14(OUTPUT_SPI_CLOCK_PIN) on output DA and CL respectively." >> ../firmware/Firmwares_for_Pimoroni_Plasma_2040.txt
cmake -DOVERRIDE_DATA_PIN=15 -DOVERRIDE_SPI_INTERFACE=spi1 -DOVERRIDE_SPI_DATA_PIN=15 -DOVERRIDE_SPI_CLOCK_PIN=14 -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
zip -j ../firmware/Pimoroni_Plasma_2040.zip ../firmware/*
- uses: actions/upload-artifact@v3
name: Upload artifacts (release Pimoroni_Plasma)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
path: |
firmware/*.zip
################################
###### Publish Releases ########
Expand Down Expand Up @@ -79,6 +163,7 @@ jobs:
tag_name: ${{ env.TAG }}
files: |
*.uf2
*.zip
draft: true
prerelease: ${{ env.preRelease }}
env:
Expand Down
44 changes: 40 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set(OUTPUT_DATA_PIN 2)
# only certain pairs of pins are allowed for selected SPI interface (refer to "readme.md")
set(OUTPUT_SPI_DATA_PIN 3)
set(OUTPUT_SPI_CLOCK_PIN 2)
set(SPI_INTERFACE spi0)
set(OUTPUT_SPI_INTERFACE spi0)

# Use multi-segment, starting index of second led strip or OFF to disable
set(SECOND_SEGMENT_INDEX OFF)
Expand Down Expand Up @@ -49,7 +49,43 @@ pico_sdk_init()
set(HyperSerialPicoCompanionLibs FreeRTOS-Kernel FreeRTOS-Kernel-Heap1 pico_stdlib pico_multicore hardware_pio hardware_dma hardware_spi)
set(HyperSerialPicoCompanionIncludes ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sdk/config)
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/generated)
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/firmwares)
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/firmware)

if(NOT CMAKE_HOST_WIN32)
string(ASCII 27 EscChar)
set(ColorReset "${EscChar}[m")
set(GreenColor "${EscChar}[32m")
set(YellowColor "${EscChar}[33m")
endif()

if (OVERRIDE_DATA_PIN)
set(OUTPUT_DATA_PIN ${OVERRIDE_DATA_PIN})
message( STATUS "${YellowColor}Overriding Neopixel Data GPIO: ${OUTPUT_DATA_PIN}${ColorReset}")
endif()

if (OVERRIDE_SPI_DATA_PIN)
set(OUTPUT_SPI_DATA_PIN ${OVERRIDE_SPI_DATA_PIN})
message( STATUS "${YellowColor}Overriding SPI Data GPIO: ${OUTPUT_SPI_DATA_PIN}${ColorReset}")
endif()

if (OVERRIDE_SPI_CLOCK_PIN)
set(OUTPUT_SPI_CLOCK_PIN ${OVERRIDE_SPI_CLOCK_PIN})
message( STATUS "${YellowColor}Overriding SPI Clock GPIO: ${OUTPUT_SPI_CLOCK_PIN}${ColorReset}")
endif()

if (OVERRIDE_SPI_INTERFACE)
set(OUTPUT_SPI_INTERFACE ${OVERRIDE_SPI_INTERFACE})
message( STATUS "${YellowColor}Overriding SPI Interface: ${OUTPUT_SPI_INTERFACE}${ColorReset}")
endif()

message( STATUS "---------------------------")
message( STATUS "Neopixel Data GPIO: ${GreenColor}${OUTPUT_DATA_PIN}${ColorReset}")
message( STATUS "SPI Data GPIO: ${GreenColor}${OUTPUT_SPI_DATA_PIN}${ColorReset}")
message( STATUS "SPI Clock GPIO: ${GreenColor}${OUTPUT_SPI_CLOCK_PIN}${ColorReset}")
message( STATUS "SPI Interface: ${GreenColor}${OUTPUT_SPI_INTERFACE}${ColorReset}")
message( STATUS "---------------------------")

add_compile_options(-ftrack-macro-expansion=0 -fno-diagnostics-show-caret -fdiagnostics-color=auto)

macro(HyperSerialPicoTarget HyperSerialPicoTargetName)
add_executable(${HyperSerialPicoTargetName} ${CMAKE_SOURCE_DIR}/source/main.cpp)
Expand All @@ -60,13 +96,13 @@ macro(HyperSerialPicoTarget HyperSerialPicoTargetName)
pico_enable_stdio_uart(${HyperSerialPicoTargetName} 0)
pico_generate_pio_header(${HyperSerialPicoTargetName} ${CMAKE_SOURCE_DIR}/pio/neopixel.pio OUTPUT_DIR ${CMAKE_SOURCE_DIR}/generated)
pico_generate_pio_header(${HyperSerialPicoTargetName} ${CMAKE_SOURCE_DIR}/pio/neopixel_ws2812b.pio OUTPUT_DIR ${CMAKE_SOURCE_DIR}/generated)
add_custom_command(TARGET ${HyperSerialPicoTargetName} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${HyperSerialPicoTargetName}.uf2 ${CMAKE_SOURCE_DIR}/firmwares)
add_custom_command(TARGET ${HyperSerialPicoTargetName} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${HyperSerialPicoTargetName}.uf2 ${CMAKE_SOURCE_DIR}/firmware)
endmacro()

# targets for different LED strips
IF(NOT SECOND_SEGMENT_INDEX)
HyperSerialPicoTarget("${CMAKE_PROJECT_NAME}_Spi")
target_compile_definitions("${CMAKE_PROJECT_NAME}_Spi" PRIVATE -DSPILED_APA102 -DSPI_INTERFACE=${SPI_INTERFACE} -DDATA_PIN=${OUTPUT_SPI_DATA_PIN} -DCLOCK_PIN=${OUTPUT_SPI_CLOCK_PIN})
target_compile_definitions("${CMAKE_PROJECT_NAME}_Spi" PRIVATE -DSPILED_APA102 -DSPI_INTERFACE=${OUTPUT_SPI_INTERFACE} -DDATA_PIN=${OUTPUT_SPI_DATA_PIN} -DCLOCK_PIN=${OUTPUT_SPI_CLOCK_PIN})
HyperSerialPicoTarget("${CMAKE_PROJECT_NAME}_sk6812Cold")
target_compile_definitions("${CMAKE_PROJECT_NAME}_sk6812Cold" PRIVATE -DNEOPIXEL_RGBW -DCOLD_WHITE -DDATA_PIN=${OUTPUT_DATA_PIN})
HyperSerialPicoTarget("${CMAKE_PROJECT_NAME}_sk6812Neutral")
Expand Down
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Adalight serial port LED driver implementation for Raspberry Pi Pico RP2040.
<p align="center"><img src="https://user-images.githubusercontent.com/69086569/236885968-baab51ba-a54b-4072-9a2a-cf867f2edb4b.png" width="250" height="250"/><img src="https://user-images.githubusercontent.com/69086569/236885360-dce9cfd7-92a8-43c6-911f-649325ee8a96.png" width="250" height="250"/></p>

# Recommended boards with a built-in level shifter
To ensure the LEDs will work properly with the Pico board, a 3.3V to 5V level shifter is needed. You can use an external one e.g. SN74AHCT125N or just buy a model of rp2040 that already has it built-in: Adafruit Feather RP2040 Scorpio (output: GPIO16-23), Pimoroni Plasma 2040 (GPIO14-15) or Pimoroni Plasma Stick 2040 W (GPIO15).
To ensure the LEDs will work properly with the Pico board, a 3.3V to 5V level shifter is needed. You can use an external one e.g. SN74AHCT125N or just buy a model of rp2040 that already has it built-in: Adafruit Feather RP2040 Scorpio (output: GPIO16-23), Adafruit ItsyBitsy RP2040 (output: GPIO14), Pimoroni Plasma 2040 (GPIO14-15) or Pimoroni Plasma Stick 2040 W (GPIO15).

<p align="center"><img src="https://user-images.githubusercontent.com/69086569/242393809-4e491159-76c7-4c1e-be0a-1f10cd5291f2.png" width="200" height="200"/><img src="https://user-images.githubusercontent.com/69086569/241395006-ee27175e-677b-4971-97bc-ed294eaa8f3b.png" width="200" height="200"/><img src="https://user-images.githubusercontent.com/69086569/241394387-f8193ed8-56d5-46c6-b406-911720aed605.png" width="200" height="200"/></p>
<p align="center"><img src="https://user-images.githubusercontent.com/69086569/242393809-4e491159-76c7-4c1e-be0a-1f10cd5291f2.png" width="200" height="200"/><img src="https://github.com/awawa-dev/HyperSerialPico/assets/69086569/e7a2a945-be12-47b1-8e48-ffc1b11c5b2f.png" width="200" height="200"/><img src="https://user-images.githubusercontent.com/69086569/241395006-ee27175e-677b-4971-97bc-ed294eaa8f3b.png" width="200" height="200"/><img src="https://user-images.githubusercontent.com/69086569/241394387-f8193ed8-56d5-46c6-b406-911720aed605.png" width="200" height="200"/></p>

# Supported LED strips
| LED strip / Device | Single lane | Multi-segment |
Expand All @@ -22,15 +22,19 @@ To ensure the LEDs will work properly with the Pico board, a 3.3V to 5V level sh
# How to flash it?
It's very easy and you don't need any special flasher.

First download the firmware directly from the [Release folder](https://github.com/awawa-dev/HyperSerialPico/releases).

For HyperHDR choose `HyperSerialPico_<type>.uf2` firmware where *type* is one of supported LEDs: sk6812 cold/neutral white, variants of ws2812 and apa102. If you are using an application other than HyperHDR, select the `classic_adalight.zip` archive, unzip it and select `classic_adalight_HyperSerialPico_<type>.uf2` firmware (note: do not use firmwares from this archive for HyperHDR, they do not support my AWA protocol extension, missing many options and are simply only backwards compatible with other applications).
1) First download the firmware directly from the [Release folder](https://github.com/awawa-dev/HyperSerialPico/releases). \
\
For HyperHDR and generic rp2040 choose `HyperSerialPico_<type>.uf2` firmware where *type* is one of supported LEDs: sk6812 cold/neutral white, variants of ws2812 and apa102. \
\
Due to the often neglected issue of the required 5 volt logic necessary for the correct operation of the supported LEDs, we want to promote rp2040 boards with a built-in 3.3V to 5V level shifter and we provide firmware compiled to their GPIO specifications. You can find these firmware & short pin-out manuals in the archives: `Adafruit_Feather_RP2040_Scorpio.zip`, `Adafruit_ItsyBitsy_2040.zip`, `Pimoroni_Plasma_2040.zip`, `Pimoroni_Plasma_Stick_2040_W.zip`. Also you can read about their specific GPIO output in the `Recommended boards with a built-in level shifter` section above. \
\
If you are using an application other than HyperHDR, select the `classic_adalight.zip` archive, unzip it and select `classic_adalight_HyperSerialPico_<type>.uf2` firmware (note: do not use firmware from this archive for HyperHDR, they do not support my AWA protocol extension, missing many options and are simply only backwards compatible with other applications).

Next put your Pico board into DFU mode:
3) Next put your Pico board into DFU mode:
* If your Pico board has only one button (`boot`) then press & hold it and connect the board to the USB port. Then you can release the button.
* If your Pico board has two buttons, connect it to the USB port. Then press & hold `boot` and `reset` buttons, then release `reset` and next release `boot` button.

In the system file explorer you should find new drive (e.g. called `RPI-RP2` drive) exposed by the Pico board. Drag & drop (or copy) the selected firmware to this drive.
3) In the system file explorer you should find new drive (e.g. called `RPI-RP2` drive) exposed by the Pico board. Drag & drop (or copy) the selected firmware to this drive.
The Pico will reset automaticly after the upload and after few seconds it will be ready to use by HyperHDR as a serial port device using Adalight driver.

# HyperHDR configuration
Expand All @@ -49,7 +53,7 @@ rp2040 allows hardware SPI on corresponding pairs of pins:
spi0 ⇒ Data/Clock: GPIO3/GPIO2, GPIO19/GPIO18, GPIO7/GPIO6
spi1 ⇒ Data/Clock: GPIO11/GPIO10, GPI15/GPIO14, GPIO27/GPI26

Pinout can be changed, but you need to make changes to `CMakeList.txt` (e.g. `OUTPUT_DATA_PIN` / `OUTPUT_SPI_DATA_PIN` / `OUTPUT_SPI_CLOCK_PIN`) and recompile the project. Also multi-segment mode can be enabled in this file: `SECOND_SEGMENT_INDEX` option at the beginning and optionally `SECOND_SEGMENT_REVERSED`. Once compiled, the results can be found in the `firmwares` folder.
Pinout can be changed, but you need to make changes to `CMakeList.txt` (e.g. `OUTPUT_DATA_PIN` / `OUTPUT_SPI_DATA_PIN` / `OUTPUT_SPI_CLOCK_PIN`) and recompile the project. Also multi-segment mode can be enabled in this file: `SECOND_SEGMENT_INDEX` option at the beginning and optionally `SECOND_SEGMENT_REVERSED`. Once compiled, the results can be found in the `firmware` folder.

Of course, you can also build your custom firmware completely online using Github Actions. The manual can be found on [wiki](https://github.com/awawa-dev/HyperSerialPico/wiki). Be sure to follow the steps in the correct order.

Expand Down

0 comments on commit d35938d

Please sign in to comment.