From f0ae617a82b561aaa6ef43ef6958961f36d95b70 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Sun, 27 Oct 2024 15:15:35 +0100 Subject: [PATCH] [examples] Add fiber version of AMNB example --- examples/nucleo_g071rb/amnb_fiber/main.cpp | 166 ++++++++++++++++++ examples/nucleo_g071rb/amnb_fiber/project.xml | 18 ++ 2 files changed, 184 insertions(+) create mode 100644 examples/nucleo_g071rb/amnb_fiber/main.cpp create mode 100644 examples/nucleo_g071rb/amnb_fiber/project.xml diff --git a/examples/nucleo_g071rb/amnb_fiber/main.cpp b/examples/nucleo_g071rb/amnb_fiber/main.cpp new file mode 100644 index 0000000000..b9c11c533a --- /dev/null +++ b/examples/nucleo_g071rb/amnb_fiber/main.cpp @@ -0,0 +1,166 @@ +/* + * 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 + +using namespace Board; +using namespace std::chrono_literals; +using namespace modm::amnb; +using Usart1 = BufferedUart>; +using Usart3 = BufferedUart>; +using Usart4 = BufferedUart; +// ---------------------------------------------------------------------------- + +Listener listeners[] = +{ + {1, [](uint8_t sender, const uint32_t& data) + { + MODM_LOG_INFO << "Node2 and Node3 received Broadcast 1 from '" << sender; + MODM_LOG_INFO << "': " << data << modm::endl; + } + }, + {2, [](uint8_t sender) + { + MODM_LOG_INFO << "Node2 and Node3 received Broadcast 2 from '" << sender << "'" << modm::endl; + } + }, +}; +Action actions[] = +{ + {1, []() -> Response + { + static uint8_t counter{0}; + MODM_LOG_INFO << "Node1 or Node3 received Action 1" << modm::endl; + return counter++; + } + }, + {2, [](const uint32_t& data) -> Response + { + static uint8_t counter{0}; + MODM_LOG_INFO << "Node1 or Node3 received Action 2 with argument: " << data << modm::endl; + return ErrorResponse(counter++); + } + }, +}; + +// Two nodes on the same device on different UARTs of course! +DeviceWrapper device1; +DeviceWrapper device2; +DeviceWrapper device3; +Node node1(device1, 1, actions); +Node node2(device2, 2, listeners); +Node node3(device3, 3, actions, listeners); + +modm::Fiber<> fiberNode1t([]{ node1.update_transmit(); }); +modm::Fiber<> fiberNode1r([]{ node1.update_receive(); }); +modm::Fiber<> fiberNode2t([]{ node2.update_transmit(); }); +modm::Fiber<> fiberNode2r([]{ node2.update_receive(); }); +modm::Fiber<> fiberNode3t([]{ node3.update_transmit(); }); +modm::Fiber<> fiberNode3r([]{ node3.update_receive(); }); + +// You need to connect D1 with D15 and with A0 +using PinNode1 = GpioC4; // D1 +using PinNode2 = GpioB8; // D15 +using PinNode3 = GpioA0; // A0 + +#undef MODM_PROTOTHREAD_STACK_SIZE +#define MODM_PROTOTHREAD_STACK_SIZE 4096 + +class Thread : public modm::pt::Protothread +{ + modm::ShortPeriodicTimer tmr{1s}; + uint32_t counter{0}; + Result res1; + Result res2; + +public: + bool inline + update() + { + PT_BEGIN(); + + while(true) + { + PT_WAIT_UNTIL(tmr.execute()); + + node1.broadcast(1, counter++); + node3.broadcast(2); + + res1 = PT_CALL(node2.request(1, 1)); + MODM_LOG_INFO << "Node1 responded with: " << res1.error(); + if (res1) { MODM_LOG_INFO << " " << *res1 << modm::endl; } + + res2 = PT_CALL(node1.request(3, 2, counter)); + MODM_LOG_INFO << "Node3 responded with: " << res2.error(); + if (res2.hasUserError()) { + MODM_LOG_INFO << " " << *res2.userError() << modm::endl; + } + + MODM_LOG_INFO << "Node1t stack=" << fiberNode1t.stack_usage() << "\nNode1r stack=" << fiberNode1r.stack_usage() << modm::endl; + MODM_LOG_INFO << "Node2t stack=" << fiberNode2t.stack_usage() << "\nNode2r stack=" << fiberNode2r.stack_usage() << modm::endl; + MODM_LOG_INFO << "Node3t stack=" << fiberNode3t.stack_usage() << "\nNode3r stack=" << fiberNode3r.stack_usage() << modm::endl; + MODM_LOG_INFO << "Thread stack=" << this->stack_usage() << modm::endl; + } + + PT_END(); + } +} +thread; + + + +// ---------------------------------------------------------------------------- +int +main() +{ + Board::initialize(); + LedD13::setOutput(); + + Usart1::connect(); + Usart1::initialize(Usart1::Parity::Even, Usart1::WordLength::Bit9); + // Use Single-Wire Half-Duplex Mode + PinNode1::configure(Gpio::OutputType::OpenDrain); + PinNode1::configure(Gpio::InputType::PullUp); + USART1->CR1 &= ~USART_CR1_UE; + USART1->CR3 = USART_CR3_HDSEL; + USART1->CR1 |= USART_CR1_UE; + + Usart3::connect(); + Usart3::initialize(Usart1::Parity::Even, Usart1::WordLength::Bit9); + // Use Single-Wire Half-Duplex Mode + PinNode2::configure(Gpio::OutputType::OpenDrain); + PinNode2::configure(Gpio::InputType::PullUp); + USART3->CR1 &= ~USART_CR1_UE; + USART3->CR3 = USART_CR3_HDSEL; + USART3->CR1 |= USART_CR1_UE; + + Usart4::connect(); + Usart4::initialize(Usart1::Parity::Even, Usart1::WordLength::Bit9); + // Use Single-Wire Half-Duplex Mode + PinNode3::configure(Gpio::OutputType::OpenDrain); + PinNode3::configure(Gpio::InputType::PullUp); + USART4->CR1 &= ~USART_CR1_UE; + USART4->CR3 = USART_CR3_HDSEL; + USART4->CR1 |= USART_CR1_UE; + + fiberNode1t.watermark_stack(); + fiberNode1r.watermark_stack(); + fiberNode2t.watermark_stack(); + fiberNode2r.watermark_stack(); + fiberNode3t.watermark_stack(); + fiberNode3r.watermark_stack(); + thread.watermark_stack(); + + modm::fiber::Scheduler::run(); + + return 0; +} diff --git a/examples/nucleo_g071rb/amnb_fiber/project.xml b/examples/nucleo_g071rb/amnb_fiber/project.xml new file mode 100644 index 0000000000..0c759874cf --- /dev/null +++ b/examples/nucleo_g071rb/amnb_fiber/project.xml @@ -0,0 +1,18 @@ + + modm:nucleo-g071rb + + + + + + + modm:platform:gpio + modm:communication:amnb + modm:platform:uart:1 + modm:platform:uart:3 + modm:platform:uart:4 + modm:build:scons + modm:processing:protothread + modm:processing:fiber + +