summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2023-07-09 16:23:54 +0200
committerThomas White <taw@physics.org>2023-07-09 16:46:03 +0200
commit7f05e911e58c8aa283b65becca4bafeb1181ba87 (patch)
treecd94b6a225d3346a6d1a84b7a8cf1d7ce5d6b12f
Initial import
-rw-r--r--CMakeLists.txt20
-rwxr-xr-xcompile9
-rw-r--r--pico_sdk_import.cmake73
-rw-r--r--pixelhub.cpp87
-rw-r--r--ws2812.pio48
5 files changed, 237 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..b7624e5
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.12)
+
+include(pico_sdk_import.cmake)
+
+project(pixelhub C CXX)
+set(CMAKE_CXX_STANDARD 17)
+
+pico_sdk_init()
+
+include(Pico-DMX/interfaceLibForPicoSDK.cmake)
+
+add_executable(pixelhub pixelhub.cpp)
+target_link_libraries(pixelhub
+ pico_stdlib
+ picodmx
+ hardware_pio)
+pico_add_extra_outputs(pixelhub)
+
+pico_generate_pio_header(pixelhub ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
+target_include_directories(pixelhub PRIVATE ${CMAKE_CURRENT_LIST_DIR})
diff --git a/compile b/compile
new file mode 100755
index 0000000..2586e78
--- /dev/null
+++ b/compile
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+export PICO_SDK_PATH=/mnt/datassd/2023/pico/pico-sdk/
+rm -rf build
+mkdir build
+cd build
+cmake .. -DPICO_BOARD=pico
+cd ..
+make -C build
diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake
new file mode 100644
index 0000000..65f8a6f
--- /dev/null
+++ b/pico_sdk_import.cmake
@@ -0,0 +1,73 @@
+# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
+
+# This can be dropped into an external project to help locate this SDK
+# It should be include()ed prior to project()
+
+if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
+ set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
+ message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
+endif ()
+
+if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
+ set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
+ message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
+endif ()
+
+if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
+ set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
+ message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
+endif ()
+
+set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
+set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
+set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
+
+if (NOT PICO_SDK_PATH)
+ if (PICO_SDK_FETCH_FROM_GIT)
+ include(FetchContent)
+ set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
+ if (PICO_SDK_FETCH_FROM_GIT_PATH)
+ get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
+ endif ()
+ # GIT_SUBMODULES_RECURSE was added in 3.17
+ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
+ FetchContent_Declare(
+ pico_sdk
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG master
+ GIT_SUBMODULES_RECURSE FALSE
+ )
+ else ()
+ FetchContent_Declare(
+ pico_sdk
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG master
+ )
+ endif ()
+
+ if (NOT pico_sdk)
+ message("Downloading Raspberry Pi Pico SDK")
+ FetchContent_Populate(pico_sdk)
+ set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
+ endif ()
+ set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
+ else ()
+ message(FATAL_ERROR
+ "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
+ )
+ endif ()
+endif ()
+
+get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
+if (NOT EXISTS ${PICO_SDK_PATH})
+ message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
+endif ()
+
+set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
+if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
+ message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
+endif ()
+
+set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
+
+include(${PICO_SDK_INIT_CMAKE_FILE})
diff --git a/pixelhub.cpp b/pixelhub.cpp
new file mode 100644
index 0000000..f876e08
--- /dev/null
+++ b/pixelhub.cpp
@@ -0,0 +1,87 @@
+/*
+ * pixelhub.c
+ *
+ * DMX to neopixel interface
+ *
+ * Copyright © 2023 Thomas White <taw@physics.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with This program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <pico/stdlib.h>
+#include <DmxInput.h>
+#include <ws2812.pio.h>
+
+const int dmx_rx_pin = 16;
+const int pixels_pin = 2;
+const int num_pixels = 8;
+const PIO led_pio = pio0;
+uint led_pio_sm;
+
+
+static inline void put_pixel(uint32_t pixel_grb) {
+ pio_sm_put_blocking(led_pio, led_pio_sm, pixel_grb << 8u);
+}
+
+
+static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
+ return ((uint32_t) (r) << 8) | ((uint32_t) (g) << 16) | (uint32_t) (b);
+}
+
+
+int main()
+{
+ DmxInput dmx_in;
+ uint offset;
+ uint8_t dmxbuf[512];
+ uint32_t pixelbuf[num_pixels];
+ int i;
+ int blink = 1;
+
+ /* Initialise DMX */
+ dmx_in.begin(dmx_rx_pin, 1, 512);
+
+ /* Initialise Neopixels */
+ led_pio_sm = pio_claim_unused_sm(led_pio, true);
+ offset = pio_add_program(led_pio, &ws2812_program);
+ ws2812_program_init(led_pio, led_pio_sm, offset, pixels_pin, 800000, false);
+
+ /* Status LED */
+ gpio_init(PICO_DEFAULT_LED_PIN);
+ gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
+
+ for ( i=0; i<num_pixels; i++ ) {
+ pixelbuf[i] = 0x00000000; /* (W)GRB */
+ }
+
+ while (1) {
+
+ dmx_in.read(dmxbuf);
+
+ for ( i=0; i<num_pixels; i++) {
+ pixelbuf[i] = urgb_u32(dmxbuf[1+3*i+0],
+ dmxbuf[1+3*i+1],
+ dmxbuf[1+3*i+2]);
+ }
+
+ for ( i=0; i<num_pixels; i++) {
+ put_pixel(pixelbuf[i]);
+ }
+
+ gpio_put(PICO_DEFAULT_LED_PIN, blink);
+ blink = 1 - blink;
+ //sleep_us(100000);
+ }
+}
diff --git a/ws2812.pio b/ws2812.pio
new file mode 100644
index 0000000..ae19a6b
--- /dev/null
+++ b/ws2812.pio
@@ -0,0 +1,48 @@
+;
+; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+;
+; SPDX-License-Identifier: BSD-3-Clause
+;
+
+.program ws2812
+.side_set 1
+
+.define public T1 2
+.define public T2 5
+.define public T3 3
+
+.lang_opt python sideset_init = pico.PIO.OUT_HIGH
+.lang_opt python out_init = pico.PIO.OUT_HIGH
+.lang_opt python out_shiftdir = 1
+
+.wrap_target
+bitloop:
+ out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls
+ jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse
+do_one:
+ jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse
+do_zero:
+ nop side 0 [T2 - 1] ; Or drive low, for a short pulse
+.wrap
+
+% c-sdk {
+#include "hardware/clocks.h"
+
+static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
+
+ pio_gpio_init(pio, pin);
+ pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
+
+ pio_sm_config c = ws2812_program_get_default_config(offset);
+ sm_config_set_sideset_pins(&c, pin);
+ sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
+ sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
+
+ int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
+ float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
+ sm_config_set_clkdiv(&c, div);
+
+ pio_sm_init(pio, sm, offset, &c);
+ pio_sm_set_enabled(pio, sm, true);
+}
+%}