From f40566beee84a53e35c963bece57fd82b297b079 Mon Sep 17 00:00:00 2001 From: Frederik Walk Date: Mon, 10 Apr 2023 11:51:45 +0200 Subject: [PATCH] Initial skeleton --- .gitignore | 4 ++ .gitmodules | 3 ++ CMakeLists.txt | 29 ++++++++++++ LICENSE | 21 +++++++++ libs/CMakeLists.txt | 1 + libs/pico-sdk | 1 + libs/pio_ws2812/CMakeLists.txt | 14 ++++++ libs/pio_ws2812/LICENSE | 21 +++++++++ libs/pio_ws2812/generated/.gitkeep | 0 libs/pio_ws2812/include/pio_ws2812/ws2812.h | 22 +++++++++ libs/pio_ws2812/src/ws2812.c | 50 +++++++++++++++++++++ libs/pio_ws2812/src/ws2812.pio | 48 ++++++++++++++++++++ src/main.cpp | 11 +++++ 13 files changed, 225 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 libs/CMakeLists.txt create mode 160000 libs/pico-sdk create mode 100644 libs/pio_ws2812/CMakeLists.txt create mode 100644 libs/pio_ws2812/LICENSE create mode 100644 libs/pio_ws2812/generated/.gitkeep create mode 100644 libs/pio_ws2812/include/pio_ws2812/ws2812.h create mode 100644 libs/pio_ws2812/src/ws2812.c create mode 100644 libs/pio_ws2812/src/ws2812.pio create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b409a9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode/ +build/ + +*.pio.h \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1891415 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libs/pico-sdk"] + path = libs/pico-sdk + url = https://github.com/raspberrypi/pico-sdk.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..07cb69f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.13) + +include(libs/pico-sdk/pico_sdk_init.cmake) + +project(DonCon2040 VERSION 0.1.0) + +pico_sdk_init() + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +add_compile_options(-Wall -Wextra -Werror) + +add_subdirectory(libs) + +file(GLOB ${PROJECT_NAME}_SOURCES src/*.cpp) + +add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_SOURCES}) + +target_include_directories(${PROJECT_NAME} + PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) + +target_link_libraries(${PROJECT_NAME} PUBLIC pico_stdlib pio_ws2812) + +pico_enable_stdio_usb(${PROJECT_NAME} 1) +pico_enable_stdio_uart(${PROJECT_NAME} 0) + +# create map/bin/hex/uf2 file in addition to ELF. +pico_add_extra_outputs(${PROJECT_NAME}) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c11a136 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Frederik Walk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt new file mode 100644 index 0000000..b44dbdc --- /dev/null +++ b/libs/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(pio_ws2812) \ No newline at end of file diff --git a/libs/pico-sdk b/libs/pico-sdk new file mode 160000 index 0000000..2ccab11 --- /dev/null +++ b/libs/pico-sdk @@ -0,0 +1 @@ +Subproject commit 2ccab115de0d42d31d6611cca19ef0cd0d2ccaa7 diff --git a/libs/pio_ws2812/CMakeLists.txt b/libs/pio_ws2812/CMakeLists.txt new file mode 100644 index 0000000..be2ad16 --- /dev/null +++ b/libs/pio_ws2812/CMakeLists.txt @@ -0,0 +1,14 @@ +file(GLOB pio_ws2812_SOURCES src/*.c) + +add_library(pio_ws2812 STATIC ${pio_ws2812_SOURCES}) + +pico_generate_pio_header(pio_ws2812 ${CMAKE_CURRENT_LIST_DIR}/src/ws2812.pio + OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated) + +target_include_directories( + pio_ws2812 + PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include + PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include/pio_ws2812 + PRIVATE ${CMAKE_CURRENT_LIST_DIR}/generated) + +target_link_libraries(pio_ws2812 PUBLIC pico_stdlib hardware_pio) diff --git a/libs/pio_ws2812/LICENSE b/libs/pio_ws2812/LICENSE new file mode 100644 index 0000000..e8a64f1 --- /dev/null +++ b/libs/pio_ws2812/LICENSE @@ -0,0 +1,21 @@ +Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/libs/pio_ws2812/generated/.gitkeep b/libs/pio_ws2812/generated/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/libs/pio_ws2812/include/pio_ws2812/ws2812.h b/libs/pio_ws2812/include/pio_ws2812/ws2812.h new file mode 100644 index 0000000..6e8ab36 --- /dev/null +++ b/libs/pio_ws2812/include/pio_ws2812/ws2812.h @@ -0,0 +1,22 @@ +#ifndef _WS2812_H_ +#define _WS2812_h_ + +#include "pico/stdlib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ws2812_init(uint8_t pin, bool is_rgbw); + +uint32_t ws2812_rgb_to_u32pixel(uint8_t r, uint8_t g, uint8_t b); +uint32_t ws2812_rgb_to_gamma_corrected_u32pixel(uint8_t r, uint8_t g, uint8_t b); + +void ws2812_put_pixel(uint32_t pixel_grb); +void ws2812_put_frame(uint32_t *frame, size_t length); + +#ifdef __cplusplus +} +#endif + +#endif // _WS2812_H_ \ No newline at end of file diff --git a/libs/pio_ws2812/src/ws2812.c b/libs/pio_ws2812/src/ws2812.c new file mode 100644 index 0000000..a4b6964 --- /dev/null +++ b/libs/pio_ws2812/src/ws2812.c @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "ws2812.h" +#include "ws2812.pio.h" + +#include "hardware/clocks.h" +#include "hardware/pio.h" + +static const uint8_t gamma_correct[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, + 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, + 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, + 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114, 115, 117, 119, 120, 122, 124, + 126, 127, 129, 131, 133, 135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, + 169, 171, 173, 175, 177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218, + 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255}; + +void ws2812_init(uint8_t pin, bool is_rgbw) { + PIO pio = pio0; + int sm = 0; + uint offset = pio_add_program(pio, &ws2812_program); + + ws2812_program_init(pio, sm, offset, pin, 800000, is_rgbw); +} + +uint32_t ws2812_rgb_to_u32pixel(uint8_t r, uint8_t g, uint8_t b) { + return ((uint32_t)(r) << 8) | ((uint32_t)(g) << 16) | (uint32_t)(b); +} + +uint32_t ws2812_rgb_to_gamma_corrected_u32pixel(uint8_t r, uint8_t g, uint8_t b) { + return ((uint32_t)(gamma_correct[r]) << 8) | ((uint32_t)(gamma_correct[g]) << 16) | (uint32_t)(gamma_correct[b]); +} + +void ws2812_put_pixel(uint32_t pixel_grb) { pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); } + +void ws2812_put_frame(uint32_t *frame, size_t length) { + for (size_t i = 0; i < length; ++i) { + ws2812_put_pixel(frame[i]); + } + sleep_us(60); +} diff --git a/libs/pio_ws2812/src/ws2812.pio b/libs/pio_ws2812/src/ws2812.pio new file mode 100644 index 0000000..df990a6 --- /dev/null +++ b/libs/pio_ws2812/src/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); +} +%} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..89eca02 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,11 @@ +#include "pico/stdlib.h" + +#include + +int main() { + stdio_init_all(); + + while (true) { + sleep_ms(1); + } +} \ No newline at end of file