Skip to content

Commit

Permalink
Add support for Adafruit ItsyBitsy RP2040 and Feather RP2040 Scorpio (#…
Browse files Browse the repository at this point in the history
…49)

* Add support for Adafruit ItsyBitsy RP2040

* Change SPI MOSI->MISO is GPIO28 (A2) for Adafruit_ItsyBitsy_RP2040

* Add support for Adafruit Feather RP2040 Scorpio

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update push-master-pico.yml

* Update push-master-pico.yml

* Update push-master.yml

* Update push-master.yml
  • Loading branch information
awawa-dev committed Jun 23, 2024
1 parent be49554 commit 2d3292a
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 53 deletions.
73 changes: 56 additions & 17 deletions .github/workflows/push-master-pico.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
run:
working-directory: ./rp2040
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: recursive

Expand All @@ -30,45 +30,83 @@ jobs:
cd build
cmake ..
cmake --build . --config Release
zip -j ../HyperSerialPico/firmware/hyperspi_pico_rp2040.zip ../HyperSerialPico/firmware/*.uf2
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifacts (commit)
if: (startsWith(github.event.ref, 'refs/tags') != true)
with:
name: commit-artifact-pico
path: |
rp2040/HyperSerialPico/firmware/*.uf2
rp2040/HyperSerialPico/firmware/*.zip
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifacts (release)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
name: release-artifact-pico
path: |
rp2040/HyperSerialPico/firmware/*.uf2
rp2040/HyperSerialPico/firmware/*.zip
- name: Build packages for Adafruit Feather RP2040 Scorpio
shell: bash
run: |
cd build
rm *.*
rm ../HyperSerialPico/firmware/*
echo "Neopixel is using GPIO16(OUTPUT_DATA_PIN) on output 0." > ../HyperSerialPico/firmware/Firmwares_for_Adafruit_Feather_RP2040_Scorpio.txt
cmake -DOVERRIDE_DATA_PIN=16 -DCMAKE_BUILD_TYPE=Release ..
echo "Neopixel is using GPIO16(OUTPUT_DATA_PIN) on output 0." > ../HyperSerialPico/firmware/Firmware_for_Adafruit_Feather_RP2040_Scorpio.txt
echo "SPI MOSI->MISO is GPIO28 (A2)" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_Feather_RP2040_Scorpio.txt
echo "SPI SCK is GPIO26 (A0)" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_Feather_RP2040_Scorpio.txt
echo "SPI CHIP_SELECT is GPIO29 (A3)" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_Feather_RP2040_Scorpio.txt
echo "SPI interface is spi1" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_Feather_RP2040_Scorpio.txt
cmake -DOVERRIDE_DATA_PIN=16 -DOVERRIDE_SPI_DATA_PIN=28 -DOVERRIDE_SPI_CLOCK_PIN=26 -DOVERRIDE_SPI_CHIP_SELECT=29 -DOVERRIDE_SPI_INTERFACE=spi1 -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
zip -j ../HyperSerialPico/firmware/Adafruit_Feather_RP2040_Scorpio.zip ../HyperSerialPico/firmware/*
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifacts (Adafruit_Feather)
if: (startsWith(github.event.ref, 'refs/tags') != true)
with:
name: commit-artifact-Adafruit_Feather
path: |
rp2040/HyperSerialPico/firmware/*.zip
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifacts (release for Adafruit_Feather)
if: startsWith(github.ref, 'refs/tags/')
with:
name: firmware-release
name: release-artifact-Adafruit_Feather
path: |
rp2040/HyperSerialPico/firmware/*.zip
- name: Build packages for Adafruit ItsyBitsy RP2040
shell: bash
run: |
cd build
rm *.*
rm ../HyperSerialPico/firmware/*
echo "Neopixel is using GPIO14(OUTPUT_DATA_PIN) on output D5." > ../HyperSerialPico/firmware/Firmware_for_Adafruit_ItsyBitsy_RP2040.txt
echo "SPI MOSI->MISO is GPIO28 (A2)" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_ItsyBitsy_RP2040.txt
echo "SPI SCK is GPIO26 (A0)" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_ItsyBitsy_RP2040.txt
echo "SPI CHIP_SELECT is GPIO29 (A3)" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_ItsyBitsy_RP2040.txt
echo "SPI interface is spi1" >> ../HyperSerialPico/firmware/Firmware_for_Adafruit_ItsyBitsy_RP2040.txt
cmake -DOVERRIDE_DATA_PIN=14 -DOVERRIDE_SPI_DATA_PIN=28 -DOVERRIDE_SPI_CLOCK_PIN=26 -DOVERRIDE_SPI_CHIP_SELECT=29 -DOVERRIDE_SPI_INTERFACE=spi1 -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
zip -j ../HyperSerialPico/firmware/Adafruit_ItsyBitsy_RP2040.zip ../HyperSerialPico/firmware/*
- uses: actions/upload-artifact@v4
name: Upload artifacts (Adafruit_ItsyBitsy)
if: (startsWith(github.event.ref, 'refs/tags') != true)
with:
name: commit-artifact-Adafruit_ItsyBitsy
path: |
rp2040/HyperSerialPico/firmware/*.zip
- uses: actions/upload-artifact@v4
name: Upload artifacts (release for Adafruit_ItsyBitsy)
if: startsWith(github.ref, 'refs/tags/')
with:
name: release-artifact-Adafruit_ItsyBitsy
path: |
rp2040/HyperSerialPico/firmware/*.zip
Expand All @@ -95,20 +133,21 @@ jobs:
if: contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta')
run: echo "preRelease=true" >> $GITHUB_ENV

- uses: actions/download-artifact@v3
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: firmware-release
path: artifacts
pattern: release-artifact-*
merge-multiple: true

# create draft release and upload artifacts
- name: Create draft release
uses: softprops/action-gh-release@v1
with:
name: HyperSPI ${{ env.VERSION }}
tag_name: ${{ env.TAG }}
files: |
*.uf2
*.zip
files: "artifacts/**"
draft: true
prerelease: ${{ env.preRelease }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9 changes: 5 additions & 4 deletions .github/workflows/push-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
Expand All @@ -38,15 +38,16 @@ jobs:
zip -j .pio/build/recovery_firmware.zip .pio/build/*.factory.bin
rm -f .pio/build/*.factory.bin
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifacts (commit)
if: (startsWith(github.event.ref, 'refs/tags') != true)
with:
name: firmware-archive
path: |
.pio/build/*.bin
.pio/build/recovery_firmware.zip
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
name: Upload artifacts (release)
if: startsWith(github.ref, 'refs/tags/')
with:
Expand Down Expand Up @@ -76,7 +77,7 @@ jobs:
if: contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta')
run: echo "preRelease=true" >> $GITHUB_ENV

- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: firmware-release

Expand Down
95 changes: 63 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Raspberry Pi acts as a master, ESP8266/ESP32/ESP32-S2/rp2040(Raspberry Pi Pico)
- SPI doesn't have any data integration check. But AWA protocol does have one
- you don't need to have 2Mb capable serial port on your ESP board
- SPI transmission is much lighter than serial communication
- There is a hardware limitation for the Rpi current design...even if you connect your grabber using USB2.0 mode, working serial port driver (used by Adalight) results in quite a large overall USB transfer. So we can replace Adalight with a pure SPI data transfer as an alternative
- There is a hardware limitation for the Rpi current design...even if you connect your grabber using USB2.0 mode, working serial port driver (used by Adalight) results in quite a large drop in overall USB transfer. So we can replace Adalight with a pure SPI data transfer as an alternative
- I needed it and I was able to implemented it 😉

# Hardware connection
Expand All @@ -33,7 +33,11 @@ As you can also notice, the pinout of the SPI0 interface is identical for the en
</tr>
<tr>
<td colspan="2"><img src="https://github.com/awawa-dev/HyperSPI/assets/69086569/7f24f87e-f7e0-43f3-a568-39d0f6beced1"/></td>
</tr>
</tr>
<tr>
<td><img src="https://github.com/awawa-dev/HyperSPI/assets/69086569/170f5718-df88-4ef2-9ed8-7d92d913aeec"/></td>
<td><img src="https://github.com/awawa-dev/HyperSPI/assets/69086569/9235c689-062e-4c62-b632-8c506b0e2e97"/></td>
</tr>
<tr>
<td colspan="2"><p align="center">or if you prefer ESP32/ESP32-S2/Esp8266</p></td>
</tr>
Expand All @@ -44,11 +48,15 @@ As you can also notice, the pinout of the SPI0 interface is identical for the en
<tr>
<td><img src="https://user-images.githubusercontent.com/69086569/216763154-ca4aa8fa-5855-43c1-86c2-d401010de675.png"/></td>
<td><img src="https://user-images.githubusercontent.com/69086569/231207350-a670bfea-a96d-4d21-9e8f-f2ca027105da.png"/></td>
</tr>
</tr>
</table>

# Example of supported boards

<p align="center">
<b>Adafruit RP2040 Scorpio and ItsyBitsy with built-in level shifter (recommended!)</b><br/>
<img src="https://github.com/awawa-dev/HyperSPI/assets/69086569/c7ef2768-357e-47ca-aa1c-543769eeb360" width="250" /><img src="https://github.com/awawa-dev/HyperSPI/assets/69086569/3e55948d-fd3d-44cb-908c-9aad8ce2715d" width="250" />
</p>

<p align="center">
<b>Esp8266 Wemos D1 mini (CH340) and Wemos D1 mini pro (CP2104)</b><br/>
Expand All @@ -60,15 +68,15 @@ As you can also notice, the pinout of the SPI0 interface is identical for the en
<img src="https://user-images.githubusercontent.com/69086569/207587620-1c4c53c8-426c-486e-a6d9-d429fd1b050d.png" width="250"/><img src="https://user-images.githubusercontent.com/69086569/207587635-b7816329-0e29-47ee-a75a-bc6c41cdc51f.png" width="250"/>
</p>

## Default pinout (can be changed for esp32 and esp32-s2)
## Default pinout (can be changed for esp32, esp32-s2 and rp2040 Pico)

| PINOUT | ESP8266 | ESP32 | ESP32-S2 lolin mini| Pico (rp2040)
|-------------|-----------|-----------|-----------|-----------|
| Clock (SCK) | GPIO 14 | GPIO 18 | GPIO 7 | GPIO 2 |
| Data (MOSI) | GPIO 13 | GPIO 23 | GPIO 11 | GPIO 4 |
| SPI Chip Select(e.g. CE0) | not used | GPIO 5 | GPIO 12 | GPIO 5 |
| GROUND | mandatory | mandatory | mandatory | mandatory |
| LED output | GPIO 2 | GPIO 2 | GPIO 2 | GPIO 14 |
| PINOUT | ESP8266 | ESP32 | ESP32-S2 | Pico (rp2040) | Adafruit rp2040<br/>Scorpio / ItsyBitsy
|-------------|-----------|-----------|-----------|-----------|-----------|
| Clock (SCK) | GPIO 14 | GPIO 18 | GPIO 7 | GPIO 2 | GPIO 26 (A0) |
| Data (MOSI) | GPIO 13 | GPIO 23 | GPIO 11 | GPIO 4 | GPIO 28 (A2) |
| SPI Chip Select(e.g. CE0) | not used | GPIO 5 | GPIO 12 | GPIO 5 | GPIO 29 (A3) |
| GROUND | mandatory | mandatory | mandatory | mandatory | mandatory |
| LED output | GPIO 2 | GPIO 2 | GPIO 2 | GPIO 14 | GPIO16 / GPIO14 |

> [!CAUTION]
> The ground connection between both GPIOs is as important as the other SPI data connections. The ground cable should be of a similar length as them and run directly next to them.
Expand Down Expand Up @@ -101,12 +109,25 @@ Or use `esptool.py` e.g.
For **RGBW LED strip** like RGBW SK6812 NEUTRAL white choose: *hyperspi_..._SK6812_RGBW_NEUTRAL.bin*
For **RGBW LED strip** like RGBW SK6812 COLD white choose: *hyperspi_..._SK6812_RGBW_COLD.bin*
For **RGB LED strip** like WS8212b or RGB SK6812 variant choose: *hyperspi_..._WS281x_RGB.bin*

## Flashing Pico boards

It's very easy and you don't need any special flasher.

Use firmware from the `hyperspi_pico_rp2040.zip` archive. Adafruit boards have their own custom firmware package inside the archive: `Adafruit_ItsyBitsy_RP2040.zip` and `Adafruit_Feather_RP2040_Scorpio.zip`

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.
The Pico will reset automaticly after the upload and after few seconds it will be ready to use.

# Software configuration (HyperHDR v17 and above)

**In HyperHDR `Image Processing→Smoothing→Update frequency` you should do not exceed the maximum capacity of the device. Read more here: [testing performance](https://github.com/awawa-dev/HyperSPI#performance-output)**

Select esp8266 protocol for ESP proprietary SPI protocol, esp32 for ESP32 boards or 'standard' for other devices.
Select `esp8266` protocol for ESP proprietary SPI protocol, `esp32` for ESP32 boards, `rp2040 (Pico)` for Pico boards or `standard` for other devices.
Make sure you set "Refresh time" to zero, "Baudrate" should be set to high but realistic value like ```25 000 000```.
Enabling "White channel calibration" is optional, if you want to fine tune the white channel balance of your sk6812 RGBW LED strip.

Expand All @@ -116,38 +137,44 @@ Enabling "White channel calibration" is optional, if you want to fine tune the w

## ESP32 & ESP32-S2 parallel multi-segment mode

| LED strip / Device | ESP32 MH-ET LIVE mini<br/>HyperSPI v9 | ESP32-S2 Lolin mini<br/>HyperSPI v9 |
| sk6812 LED strip / Device | ESP32 MH-ET LIVE mini<br/>HyperSPI v9 | ESP32-S2 Lolin mini<br/>HyperSPI v9 |
|-----------------------------------------------------------------------------------------|-----------------------|----------------------|
| 300LEDs sk6812<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=150 | 100 | 100 |
| 600LEDs sk6812<br>Refresh rate/continues output=83Hz<br>SECOND_SEGMENT_START_INDEX=300 | 83 | 83 |
| 900LEDs sk6812<br>Refresh rate/continues output=55Hz <br>SECOND_SEGMENT_START_INDEX=450 | 54-55 | 55 |
| 300 RGBW LEDs<br>Refresh rate/continues output=100Hz<br>SECOND_SEGMENT_START_INDEX=150 | 100 | 100 |
| 600 RGBW LEDs<br>Refresh rate/continues output=83Hz<br>SECOND_SEGMENT_START_INDEX=300 | 83 | 83 |
| 900 RGBW LEDs<br>Refresh rate/continues output=55Hz <br>SECOND_SEGMENT_START_INDEX=450 | 54-55 | 55 |

## ESP32
## SP8266 / ESP32

| LED strip / Device | ESP32 MH ET Live<br/>HyperSPI v9 | ESP32-S2 Lolin mini<br/>HyperSPI v9 |
|------------------------------------------------|-----------------|--------------------|
| 300LEDs RGBW<br>Refresh rate/continues output=83Hz | 83 | 83 |
| 600LEDs RGBW<br>Refresh rate/continues output=43Hz | 42-43 | 42 |
| 900LEDs RGBW<br>Refresh rate/continues output=28Hz | 28 | 28 |
| sk6812 LED strip / Device | ESP32 MH ET Live<br/>HyperSPI v9 | ESP32-S2 Lolin mini<br/>HyperSPI v9 | ESP8266 Wemos D1 Pro<br/>HyperSPI v9 |
|------------------------------------------------|-----------------|--------------------|---------------------|
| 300 RGBW LEDs<br>continues output=83/70Hz | 83 | 83 | 70 |
| 600 RGBW LEDs<br>continues output=43/33Hz | 42-43 | 42 | 33 |
| 900 RGBW LEDs<br>continues output=28/22Hz | 28 | 28 | 22 |

## ESP8266
# Compiling

| LED strip / Device | ESP8266 Wemos D1 Pro<br/>HyperSPI v9 |
|------------------------------------------------|---------------------|
| 300LEDs RGBW<br>Refresh rate/continues output=70Hz | 70 |
| 600LEDs RGBW<br>Refresh rate/continues output=33Hz | 33 |
| 900LEDs RGBW<br>Refresh rate/continues output=22Hz | 22 |
## ESP8266 / ESP32

# Compiling

Currently we use PlatformIO to compile the project. Install [Visual Studio Code](https://code.visualstudio.com/) and add [PlatformIO plugin](https://platformio.org/).
This environment will take care of everything and compile the firmware for you. Low-level LED strip support is provided by my highly optimizated (pre-fill I2S DMA modes, turbo I2S parallel mode for up to 2 segments etc) version of Neopixelbus library: [link](https://github.com/awawa-dev/NeoPixelBus).

But there is also an alternative and an easier way. Just fork the project and enable its Github Action. Use the online editor to make changes to the ```platformio.ini``` file, for example change default pin-outs or enable multi-segments support, and save it. Github Action will compile new firmware automatically in the Artifacts archive. It has never been so easy! **Just remember to follow the steps in the correct order otherwise the Github Action may not be triggered the first time after saving the changes.**
## Pico rp2040

Use Pico SDK and Visual Code to open ```rp2040``` folder. Edit ```rp2040\CMakeLists.txt``` configuration file if you need to apply changes.

## Github Action

But there is also an alternative and an easier way. Just fork the project and enable its Github Action. Use the online editor to make changes:
- esp8266/ESP32 boards: to the ```platformio.ini``` file
- rp2040 Pico boards: to the ```rp2040\CMakeLists.txt``` file

for example change default pin-outs or enable multi-segments support, and save it. Github Action will compile new firmware automatically in the Artifacts archive. It has never been so easy! **Just remember to follow the steps in the correct order otherwise the Github Action may not be triggered the first time after saving the changes.**

Tutorial: https://github.com/awawa-dev/HyperSPI/wiki

# Multi-Segment Wiring (ESP32 and ESP32-S2 only)
# Multi-Segment Wiring (ESP32, ESP32-S2 and Pico rp2040 boards only)

## ESP32

Using parallel multi-segment allows you to double your Neopixel (e.g. sk6812 RGBW) LED strip refresh rate by dividing it into two smaller equal parts. Both smaller segments are perfectly in sync so you don't need to worry about it. Proposed example of building a multisegment:
- Divide a long or dense strip of LEDs into 2 smaller equal parts. So `SECOND_SEGMENT_START_INDEX` in the HyperSPI firmware is the total number of LEDs divided by 2.
Expand All @@ -173,6 +200,10 @@ build_flags = -DNEOPIXEL_RGB -DDATA_PIN=2 ${env.build_flags} -DSECOND_SEGMENT_ST
Implementation example:
- The diagram of the board for WS2812b/SK6812 including ESP32 and the SN74AHCT125N 74AHCT125 [level shifter](https://github.com/awawa-dev/HyperHDR/wiki/Level-Shifter).

## Pico rp2040

Edit ```rp2040\CMakeLists.txt``` file and recompile the project.

![HyperSPI](https://user-images.githubusercontent.com/85223482/222923979-f344349a-1f8b-4195-94ca-51721923359e.png)

# Performance/debug output
Expand Down
Loading

0 comments on commit 2d3292a

Please sign in to comment.