From 9e5e77e1dfbe7db863f551d3014cc6eeba62faef Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Sun, 10 Jul 2022 18:31:34 +0200 Subject: [PATCH 1/6] [ws2812] copied spi transfer from apa102 --- src/modm/driver/pwm/ws2812b.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/modm/driver/pwm/ws2812b.hpp b/src/modm/driver/pwm/ws2812b.hpp index 0f064f712d..eab9ae8f69 100644 --- a/src/modm/driver/pwm/ws2812b.hpp +++ b/src/modm/driver/pwm/ws2812b.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace modm { @@ -100,13 +101,10 @@ class Ws2812b return {color[1], color[0], color[2]}; } - void + modm::ResumableResult write() { - for (const auto value : data) { - while (not SpiMaster::Hal::isTransmitRegisterEmpty()) ; - SpiMaster::Hal::write(value); - } + return SpiMaster::transfer(data, nullptr, length+1); } }; From 367dc712a0cf346293ad62130b6d64e7c0047662 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Sun, 10 Jul 2022 19:10:08 +0200 Subject: [PATCH 2/6] [ws2812] resumable function example and bug --- examples/nucleo_f411re/ws2812b_dma/main.cpp | 84 +++++++++++++++++++ .../nucleo_f411re/ws2812b_dma/project.xml | 16 ++++ src/modm/driver/pwm/ws2812.lb | 1 + src/modm/driver/pwm/ws2812b.hpp | 6 +- 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 examples/nucleo_f411re/ws2812b_dma/main.cpp create mode 100644 examples/nucleo_f411re/ws2812b_dma/project.xml diff --git a/examples/nucleo_f411re/ws2812b_dma/main.cpp b/examples/nucleo_f411re/ws2812b_dma/main.cpp new file mode 100644 index 0000000000..6c6005ab41 --- /dev/null +++ b/examples/nucleo_f411re/ws2812b_dma/main.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019, Niklas Hauser + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include + +using namespace Board; + +using Output = Board::D11; +using DmaRx = Dma2::Channel0; +using DmaTx = Dma2::Channel3; +using SpiLed = SpiMaster1_Dma; +modm::Ws2812b leds; +modm::ShortPeriodicTimer tmr{33ms}; + +constexpr uint8_t max = 62; +uint8_t r=0, g=max/3, b=max/3*2; + +class Ws2812Thread : public modm::pt::Protothread +{ +public: + + bool + update() + { + PT_BEGIN(); + + LedD13::setOutput(); + Dma2::enable(); + leds.initialize(); + + while (true) + { + for (size_t ii=0; ii < leds.size; ii++) + { + leds.setColor(ii, + {modm::ui::table22_8_256[r*3/2], + modm::ui::table22_8_256[g*3/2], + modm::ui::table22_8_256[b*3/2]}); + if (r++ >= max) r = 0; + if (g++ >= max) g = 0; + if (b++ >= max) b = 0; + } + PT_CALL(leds.write()); + + LedD13::toggle(); + timeout.restart(500ms); + PT_WAIT_UNTIL(timeout.isExpired()); + } + + PT_END(); + } + +private: + modm::ShortTimeout timeout; +}; + +Ws2812Thread ws2812_thread; + +int +main() +{ + Board::initialize(); + + + + while (true) + { + ws2812_thread.update(); + } + + return 0; +} diff --git a/examples/nucleo_f411re/ws2812b_dma/project.xml b/examples/nucleo_f411re/ws2812b_dma/project.xml new file mode 100644 index 0000000000..0cf59b326f --- /dev/null +++ b/examples/nucleo_f411re/ws2812b_dma/project.xml @@ -0,0 +1,16 @@ + + + modm:nucleo-f411re + + + + + modm:driver:ws2812 + modm:platform:spi:1 + modm:platform:dma + modm:ui:led + modm:build:scons + modm:processing:protothread + modm:processing:timer + + diff --git a/src/modm/driver/pwm/ws2812.lb b/src/modm/driver/pwm/ws2812.lb index 0e971d442f..29eeb259d9 100644 --- a/src/modm/driver/pwm/ws2812.lb +++ b/src/modm/driver/pwm/ws2812.lb @@ -43,6 +43,7 @@ def prepare(module, options): ":architecture:spi", ":architecture:unaligned", ":math:units", + ":processing:resumable", ":ui:color") return options[":target"].identifier.platform == "stm32" diff --git a/src/modm/driver/pwm/ws2812b.hpp b/src/modm/driver/pwm/ws2812b.hpp index eab9ae8f69..dd5e48a4e0 100644 --- a/src/modm/driver/pwm/ws2812b.hpp +++ b/src/modm/driver/pwm/ws2812b.hpp @@ -21,7 +21,7 @@ namespace modm /// @ingroup modm_driver_ws2812 template< class SpiMaster, class Output, size_t LEDs > -class Ws2812b +class Ws2812b : protected modm::NestedResumable<3> { protected: // 7654 3210 7654 3210 7654 3210 static constexpr uint32_t base_mask = 0b0010'0100'1001'0010'0100'1001; @@ -104,7 +104,9 @@ class Ws2812b modm::ResumableResult write() { - return SpiMaster::transfer(data, nullptr, length+1); + RF_BEGIN(); + RF_CALL(SpiMaster::transfer(data, nullptr, length+1)); + RF_END_RETURN(); } }; From 3d40be4304f26f7b10fa63f4d4263cc3f34f7895 Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Sat, 27 May 2023 00:23:41 +0200 Subject: [PATCH 3/6] added usesDma --- examples/stm32f469_discovery/ws2812b/main.cpp | 52 ++++++++++++++++ .../stm32f469_discovery/ws2812b/project.xml | 13 ++++ .../stm32f469_discovery/ws2812b_dma/main.cpp | 62 +++++++++++++++++++ .../ws2812b_dma/project.xml | 15 +++++ .../architecture/interface/spi_master.hpp | 1 + src/modm/driver/pwm/ws2812b.hpp | 13 ++++ src/modm/platform/spi/stm32/spi_master.hpp.in | 1 + .../platform/spi/stm32/spi_master_dma.hpp.in | 3 + 8 files changed, 160 insertions(+) create mode 100644 examples/stm32f469_discovery/ws2812b/main.cpp create mode 100644 examples/stm32f469_discovery/ws2812b/project.xml create mode 100644 examples/stm32f469_discovery/ws2812b_dma/main.cpp create mode 100644 examples/stm32f469_discovery/ws2812b_dma/project.xml diff --git a/examples/stm32f469_discovery/ws2812b/main.cpp b/examples/stm32f469_discovery/ws2812b/main.cpp new file mode 100644 index 0000000000..40048adf5f --- /dev/null +++ b/examples/stm32f469_discovery/ws2812b/main.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, Niklas Hauser + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include + +using namespace Board; + +using Output = Board::D11; +modm::Ws2812b leds; +modm::ShortPeriodicTimer tmr{33ms}; + +int +main() +{ + Board::initialize(); + LedD13::setOutput(); + leds.initialize(); + + constexpr uint8_t max = 60; + uint8_t r=0, g=max/3, b=max/3*2; + + while (true) + { + for (size_t ii=0; ii < leds.size; ii++) + { + leds.setColor(ii, + {modm::ui::table22_8_256[r*3/2], + modm::ui::table22_8_256[g*3/2], + modm::ui::table22_8_256[b*3/2]}); + if (r++ >= max) r = 0; + if (g++ >= max) g = 0; + if (b++ >= max) b = 0; + } + leds.write(); + + while(not tmr.execute()) ; + LedD13::toggle(); + } + + return 0; +} diff --git a/examples/stm32f469_discovery/ws2812b/project.xml b/examples/stm32f469_discovery/ws2812b/project.xml new file mode 100644 index 0000000000..e7169ab769 --- /dev/null +++ b/examples/stm32f469_discovery/ws2812b/project.xml @@ -0,0 +1,13 @@ + + + modm:disco-f469ni + + + + + modm:driver:ws2812 + modm:platform:spi:2 + modm:ui:led + modm:build:scons + + diff --git a/examples/stm32f469_discovery/ws2812b_dma/main.cpp b/examples/stm32f469_discovery/ws2812b_dma/main.cpp new file mode 100644 index 0000000000..2480e49cd0 --- /dev/null +++ b/examples/stm32f469_discovery/ws2812b_dma/main.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019, Niklas Hauser + * Copyright (c) 2023, Henrik Hose + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include + +using namespace Board; + +using Output = Board::D11; +using DmaRx = Dma1::Channel3; +using DmaTx = Dma1::Channel4; +using SpiLed = SpiMaster2_Dma; +// using SpiLed = SpiMaster2; // for non-dma version +modm::Ws2812b leds; +modm::ShortPeriodicTimer tmr{33ms}; + +constexpr uint8_t max = 62; +uint8_t r=0, g=max/3, b=max/3*2; + +int +main() +{ + Board::initialize(); + LedD13::setOutput(); + Dma1::enable(); + leds.initialize(); + + constexpr uint8_t max = 60; + uint8_t r=0, g=max/3, b=max/3*2; + + while (true) + { + for (size_t ii=0; ii < leds.size; ii++) + { + leds.setColor(ii, + {modm::ui::table22_8_256[r*3/2], + modm::ui::table22_8_256[g*3/2], + modm::ui::table22_8_256[b*3/2]}); + if (r++ >= max) r = 0; + if (g++ >= max) g = 0; + if (b++ >= max) b = 0; + } + leds.write(); + + while(not tmr.execute()) ; + LedD13::toggle(); + } + + return 0; +} diff --git a/examples/stm32f469_discovery/ws2812b_dma/project.xml b/examples/stm32f469_discovery/ws2812b_dma/project.xml new file mode 100644 index 0000000000..16526fc699 --- /dev/null +++ b/examples/stm32f469_discovery/ws2812b_dma/project.xml @@ -0,0 +1,15 @@ + + + modm:disco-f469ni + + + + + modm:driver:ws2812 + modm:platform:spi:2 + modm:platform:dma + modm:ui:led + modm:build:scons + modm:processing:timer + + diff --git a/src/modm/architecture/interface/spi_master.hpp b/src/modm/architecture/interface/spi_master.hpp index 0bcbe52ccc..94aa1bafeb 100644 --- a/src/modm/architecture/interface/spi_master.hpp +++ b/src/modm/architecture/interface/spi_master.hpp @@ -155,6 +155,7 @@ class SpiMaster : public ::modm::PeripheralDriver, public Spi */ static modm::ResumableResult transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + #endif }; diff --git a/src/modm/driver/pwm/ws2812b.hpp b/src/modm/driver/pwm/ws2812b.hpp index dd5e48a4e0..7defea1306 100644 --- a/src/modm/driver/pwm/ws2812b.hpp +++ b/src/modm/driver/pwm/ws2812b.hpp @@ -103,11 +103,24 @@ class Ws2812b : protected modm::NestedResumable<3> modm::ResumableResult write() + requires SpiMaster::usesDma { RF_BEGIN(); RF_CALL(SpiMaster::transfer(data, nullptr, length+1)); RF_END_RETURN(); } + + modm::ResumableResult + write() + { + RF_BEGIN(); + for (const auto value : data) { + while (not SpiMaster::Hal::isTransmitRegisterEmpty()) ; + SpiMaster::Hal::write(value); + } + RF_END_RETURN(); + } + }; } // namespace modm diff --git a/src/modm/platform/spi/stm32/spi_master.hpp.in b/src/modm/platform/spi/stm32/spi_master.hpp.in index 87999cfa98..023e9eaa52 100644 --- a/src/modm/platform/spi/stm32/spi_master.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master.hpp.in @@ -153,6 +153,7 @@ public: static modm::ResumableResult transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + }; } // namespace platform diff --git a/src/modm/platform/spi/stm32/spi_master_dma.hpp.in b/src/modm/platform/spi/stm32/spi_master_dma.hpp.in index 1f53b2eb1c..840b76500e 100644 --- a/src/modm/platform/spi/stm32/spi_master_dma.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master_dma.hpp.in @@ -74,6 +74,9 @@ public: static modm::ResumableResult transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + constexpr bool + usesDma(){return true;}; + private: static void handleDmaTransferError(); From e9dabe6e0c11057cbe7918791a149975a496ab0c Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Sat, 27 May 2023 00:34:49 +0200 Subject: [PATCH 4/6] removed f411 example, because I can not test it... --- examples/nucleo_f411re/ws2812b_dma/main.cpp | 84 ------------------- .../nucleo_f411re/ws2812b_dma/project.xml | 16 ---- 2 files changed, 100 deletions(-) delete mode 100644 examples/nucleo_f411re/ws2812b_dma/main.cpp delete mode 100644 examples/nucleo_f411re/ws2812b_dma/project.xml diff --git a/examples/nucleo_f411re/ws2812b_dma/main.cpp b/examples/nucleo_f411re/ws2812b_dma/main.cpp deleted file mode 100644 index 6c6005ab41..0000000000 --- a/examples/nucleo_f411re/ws2812b_dma/main.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2019, Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -// ---------------------------------------------------------------------------- - -#include -#include -#include -#include -#include - -using namespace Board; - -using Output = Board::D11; -using DmaRx = Dma2::Channel0; -using DmaTx = Dma2::Channel3; -using SpiLed = SpiMaster1_Dma; -modm::Ws2812b leds; -modm::ShortPeriodicTimer tmr{33ms}; - -constexpr uint8_t max = 62; -uint8_t r=0, g=max/3, b=max/3*2; - -class Ws2812Thread : public modm::pt::Protothread -{ -public: - - bool - update() - { - PT_BEGIN(); - - LedD13::setOutput(); - Dma2::enable(); - leds.initialize(); - - while (true) - { - for (size_t ii=0; ii < leds.size; ii++) - { - leds.setColor(ii, - {modm::ui::table22_8_256[r*3/2], - modm::ui::table22_8_256[g*3/2], - modm::ui::table22_8_256[b*3/2]}); - if (r++ >= max) r = 0; - if (g++ >= max) g = 0; - if (b++ >= max) b = 0; - } - PT_CALL(leds.write()); - - LedD13::toggle(); - timeout.restart(500ms); - PT_WAIT_UNTIL(timeout.isExpired()); - } - - PT_END(); - } - -private: - modm::ShortTimeout timeout; -}; - -Ws2812Thread ws2812_thread; - -int -main() -{ - Board::initialize(); - - - - while (true) - { - ws2812_thread.update(); - } - - return 0; -} diff --git a/examples/nucleo_f411re/ws2812b_dma/project.xml b/examples/nucleo_f411re/ws2812b_dma/project.xml deleted file mode 100644 index 0cf59b326f..0000000000 --- a/examples/nucleo_f411re/ws2812b_dma/project.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - modm:nucleo-f411re - - - - - modm:driver:ws2812 - modm:platform:spi:1 - modm:platform:dma - modm:ui:led - modm:build:scons - modm:processing:protothread - modm:processing:timer - - From 3efe5c68e1e536c90c9ac8dd149e129c746a303b Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Sat, 27 May 2023 00:57:59 +0200 Subject: [PATCH 5/6] fix --- examples/stm32f469_discovery/ws2812b_dma/main.cpp | 2 +- src/modm/driver/pwm/ws2812b.hpp | 2 +- src/modm/platform/spi/stm32/spi_master_dma.hpp.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/stm32f469_discovery/ws2812b_dma/main.cpp b/examples/stm32f469_discovery/ws2812b_dma/main.cpp index 2480e49cd0..aefea4373c 100644 --- a/examples/stm32f469_discovery/ws2812b_dma/main.cpp +++ b/examples/stm32f469_discovery/ws2812b_dma/main.cpp @@ -55,7 +55,7 @@ main() leds.write(); while(not tmr.execute()) ; - LedD13::toggle(); + // LedD13::toggle(); } return 0; diff --git a/src/modm/driver/pwm/ws2812b.hpp b/src/modm/driver/pwm/ws2812b.hpp index 7defea1306..bf9a201b05 100644 --- a/src/modm/driver/pwm/ws2812b.hpp +++ b/src/modm/driver/pwm/ws2812b.hpp @@ -103,7 +103,7 @@ class Ws2812b : protected modm::NestedResumable<3> modm::ResumableResult write() - requires SpiMaster::usesDma + requires (SpiMaster::usesDma()) { RF_BEGIN(); RF_CALL(SpiMaster::transfer(data, nullptr, length+1)); diff --git a/src/modm/platform/spi/stm32/spi_master_dma.hpp.in b/src/modm/platform/spi/stm32/spi_master_dma.hpp.in index 840b76500e..023f1193eb 100644 --- a/src/modm/platform/spi/stm32/spi_master_dma.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master_dma.hpp.in @@ -74,7 +74,7 @@ public: static modm::ResumableResult transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); - constexpr bool + static constexpr bool usesDma(){return true;}; private: From 908829f1164b2bae79931cdcfb98eba94256554d Mon Sep 17 00:00:00 2001 From: Henrik Hose Date: Sat, 27 May 2023 01:03:09 +0200 Subject: [PATCH 6/6] fix; missing usesDma in rp dma spi --- src/modm/platform/spi/rp/spi_master_dma.hpp.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modm/platform/spi/rp/spi_master_dma.hpp.in b/src/modm/platform/spi/rp/spi_master_dma.hpp.in index 0b59e3f2f3..d4d7e872df 100644 --- a/src/modm/platform/spi/rp/spi_master_dma.hpp.in +++ b/src/modm/platform/spi/rp/spi_master_dma.hpp.in @@ -84,6 +84,9 @@ public: waitCompleted([](){}); } + static constexpr bool + usesDma(){return true;}; + private: // needed for transfers where no RX or TX buffers are given static inline uint8_t dmaDummy{0};