diff --git a/examples/stm32f469_discovery/ws2812b_dma/main.cpp b/examples/stm32f469_discovery/ws2812b_dma/main.cpp new file mode 100644 index 0000000000..5efc5e08e4 --- /dev/null +++ b/examples/stm32f469_discovery/ws2812b_dma/main.cpp @@ -0,0 +1,61 @@ +/* + * 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 = 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();