|
| 1 | +/* |
| 2 | + * Copyright (c) 2019, Niklas Hauser |
| 3 | + * |
| 4 | + * This file is part of the modm project. |
| 5 | + * |
| 6 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 7 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 8 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 9 | + */ |
| 10 | + |
| 11 | +#include <modm/board.hpp> |
| 12 | +#include <modm/communication/amnb.hpp> |
| 13 | +#include <modm/processing.hpp> |
| 14 | + |
| 15 | +using namespace Board; |
| 16 | +using namespace std::chrono_literals; |
| 17 | +using namespace modm::amnb; |
| 18 | +using Usart1 = BufferedUart<UsartHal1, UartRxBuffer<32>>; |
| 19 | +using Usart3 = BufferedUart<UsartHal3, UartRxBuffer<16>>; |
| 20 | +using Usart4 = BufferedUart<UsartHal4>; |
| 21 | +// ---------------------------------------------------------------------------- |
| 22 | + |
| 23 | +Listener listeners[] = |
| 24 | +{ |
| 25 | + {1, [](uint8_t sender, const uint32_t& data) |
| 26 | + { |
| 27 | + MODM_LOG_INFO << "Node2 and Node3 received Broadcast 1 from '" << sender; |
| 28 | + MODM_LOG_INFO << "': " << data << modm::endl; |
| 29 | + } |
| 30 | + }, |
| 31 | + {2, [](uint8_t sender) |
| 32 | + { |
| 33 | + MODM_LOG_INFO << "Node2 and Node3 received Broadcast 2 from '" << sender << "'" << modm::endl; |
| 34 | + } |
| 35 | + }, |
| 36 | +}; |
| 37 | +Action actions[] = |
| 38 | +{ |
| 39 | + {1, []() -> Response |
| 40 | + { |
| 41 | + static uint8_t counter{0}; |
| 42 | + MODM_LOG_INFO << "Node1 or Node3 received Action 1" << modm::endl; |
| 43 | + return counter++; |
| 44 | + } |
| 45 | + }, |
| 46 | + {2, [](const uint32_t& data) -> Response |
| 47 | + { |
| 48 | + static uint8_t counter{0}; |
| 49 | + MODM_LOG_INFO << "Node1 or Node3 received Action 2 with argument: " << data << modm::endl; |
| 50 | + return ErrorResponse(counter++); |
| 51 | + } |
| 52 | + }, |
| 53 | +}; |
| 54 | + |
| 55 | +// Two nodes on the same device on different UARTs of course! |
| 56 | +DeviceWrapper<Usart1> device1; |
| 57 | +DeviceWrapper<Usart3> device2; |
| 58 | +DeviceWrapper<Usart4> device3; |
| 59 | +Node node1(device1, 1, actions); |
| 60 | +Node node2(device2, 2, listeners); |
| 61 | +Node node3(device3, 3, actions, listeners); |
| 62 | + |
| 63 | +modm::Fiber<> fiberNode1t([]{ node1.update_transmit(); }); |
| 64 | +modm::Fiber<> fiberNode1r([]{ node1.update_receive(); }); |
| 65 | +modm::Fiber<> fiberNode2t([]{ node2.update_transmit(); }); |
| 66 | +modm::Fiber<> fiberNode2r([]{ node2.update_receive(); }); |
| 67 | +modm::Fiber<> fiberNode3t([]{ node3.update_transmit(); }); |
| 68 | +modm::Fiber<> fiberNode3r([]{ node3.update_receive(); }); |
| 69 | + |
| 70 | +// You need to connect D1 with D15 and with A0 |
| 71 | +using PinNode1 = GpioC4; // D1 |
| 72 | +using PinNode2 = GpioB8; // D15 |
| 73 | +using PinNode3 = GpioA0; // A0 |
| 74 | + |
| 75 | +#undef MODM_PROTOTHREAD_STACK_SIZE |
| 76 | +#define MODM_PROTOTHREAD_STACK_SIZE 4096 |
| 77 | + |
| 78 | +class Thread : public modm::pt::Protothread |
| 79 | +{ |
| 80 | + modm::ShortPeriodicTimer tmr{1s}; |
| 81 | + uint32_t counter{0}; |
| 82 | + Result<uint8_t> res1; |
| 83 | + Result<uint8_t, uint8_t> res2; |
| 84 | + |
| 85 | +public: |
| 86 | + bool inline |
| 87 | + update() |
| 88 | + { |
| 89 | + PT_BEGIN(); |
| 90 | + |
| 91 | + while(true) |
| 92 | + { |
| 93 | + PT_WAIT_UNTIL(tmr.execute()); |
| 94 | + |
| 95 | + node1.broadcast(1, counter++); |
| 96 | + node3.broadcast(2); |
| 97 | + |
| 98 | + res1 = PT_CALL(node2.request<uint8_t>(1, 1)); |
| 99 | + MODM_LOG_INFO << "Node1 responded with: " << res1.error(); |
| 100 | + if (res1) { MODM_LOG_INFO << " " << *res1 << modm::endl; } |
| 101 | + |
| 102 | + res2 = PT_CALL(node1.request<uint8_t, uint8_t>(3, 2, counter)); |
| 103 | + MODM_LOG_INFO << "Node3 responded with: " << res2.error(); |
| 104 | + if (res2.hasUserError()) { |
| 105 | + MODM_LOG_INFO << " " << *res2.userError() << modm::endl; |
| 106 | + } |
| 107 | + |
| 108 | + MODM_LOG_INFO << "Node1t stack=" << fiberNode1t.stack_usage() << "\nNode1r stack=" << fiberNode1r.stack_usage() << modm::endl; |
| 109 | + MODM_LOG_INFO << "Node2t stack=" << fiberNode2t.stack_usage() << "\nNode2r stack=" << fiberNode2r.stack_usage() << modm::endl; |
| 110 | + MODM_LOG_INFO << "Node3t stack=" << fiberNode3t.stack_usage() << "\nNode3r stack=" << fiberNode3r.stack_usage() << modm::endl; |
| 111 | + MODM_LOG_INFO << "Thread stack=" << this->stack_usage() << modm::endl; |
| 112 | + } |
| 113 | + |
| 114 | + PT_END(); |
| 115 | + } |
| 116 | +} |
| 117 | +thread; |
| 118 | + |
| 119 | + |
| 120 | + |
| 121 | +// ---------------------------------------------------------------------------- |
| 122 | +int |
| 123 | +main() |
| 124 | +{ |
| 125 | + Board::initialize(); |
| 126 | + LedD13::setOutput(); |
| 127 | + |
| 128 | + Usart1::connect<PinNode1::Tx>(); |
| 129 | + Usart1::initialize<SystemClock, 115200>(Usart1::Parity::Even, Usart1::WordLength::Bit9); |
| 130 | + // Use Single-Wire Half-Duplex Mode |
| 131 | + PinNode1::configure(Gpio::OutputType::OpenDrain); |
| 132 | + PinNode1::configure(Gpio::InputType::PullUp); |
| 133 | + USART1->CR1 &= ~USART_CR1_UE; |
| 134 | + USART1->CR3 = USART_CR3_HDSEL; |
| 135 | + USART1->CR1 |= USART_CR1_UE; |
| 136 | + |
| 137 | + Usart3::connect<PinNode2::Tx>(); |
| 138 | + Usart3::initialize<SystemClock, 115200>(Usart1::Parity::Even, Usart1::WordLength::Bit9); |
| 139 | + // Use Single-Wire Half-Duplex Mode |
| 140 | + PinNode2::configure(Gpio::OutputType::OpenDrain); |
| 141 | + PinNode2::configure(Gpio::InputType::PullUp); |
| 142 | + USART3->CR1 &= ~USART_CR1_UE; |
| 143 | + USART3->CR3 = USART_CR3_HDSEL; |
| 144 | + USART3->CR1 |= USART_CR1_UE; |
| 145 | + |
| 146 | + Usart4::connect<PinNode3::Tx>(); |
| 147 | + Usart4::initialize<SystemClock, 115200>(Usart1::Parity::Even, Usart1::WordLength::Bit9); |
| 148 | + // Use Single-Wire Half-Duplex Mode |
| 149 | + PinNode3::configure(Gpio::OutputType::OpenDrain); |
| 150 | + PinNode3::configure(Gpio::InputType::PullUp); |
| 151 | + USART4->CR1 &= ~USART_CR1_UE; |
| 152 | + USART4->CR3 = USART_CR3_HDSEL; |
| 153 | + USART4->CR1 |= USART_CR1_UE; |
| 154 | + |
| 155 | + fiberNode1t.watermark_stack(); |
| 156 | + fiberNode1r.watermark_stack(); |
| 157 | + fiberNode2t.watermark_stack(); |
| 158 | + fiberNode2r.watermark_stack(); |
| 159 | + fiberNode3t.watermark_stack(); |
| 160 | + fiberNode3r.watermark_stack(); |
| 161 | + thread.watermark_stack(); |
| 162 | + |
| 163 | + modm::fiber::Scheduler::run(); |
| 164 | + |
| 165 | + return 0; |
| 166 | +} |
0 commit comments