diff --git a/Firmware/src/Communication/Serial/SerialReceiver.h b/Firmware/src/Communication/Serial/SerialReceiver.h new file mode 100644 index 0000000..ae5b224 --- /dev/null +++ b/Firmware/src/Communication/Serial/SerialReceiver.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace comm { +namespace serial { +template class SerialReceiver { +public: + SerialReceiver(HardwareSerial &port, + freertos::Queue &messageQueue, + UBaseType_t priority, BaseType_t coreID) + : port{port}, messageQueue{messageQueue}, + serialReceiverTask{ + exec, "receive serial data", stackDepth, this, priority, coreID} {} + +private: + static void exec(void *receiverPtr) { + freertos::sleep(20); // wait until Serial port has been initialized + SerialReceiver *receiver = + static_cast *>(receiverPtr); + + while (true) { + receiver->magicNumberBuf.clear(); + receiver->magicNumberBuf.resize(receiver->magicNumber.length()); + size_t availableBytes = receiver->port.available(); + if (availableBytes >= receiver->magicNumber.length() + 1) { + receiver->port.readBytes(receiver->magicNumberBuf.data(), + receiver->magicNumber.length()); + receiver->port.println(receiver->magicNumberBuf == + receiver->magicNumber); + + uint8_t size; + receiver->port.readBytes(&size, sizeof(size)); + if (receiver->port.available() >= size) { + message::Message &msg = receiver->buffer.pop(); + msg.second.lock(); + msg.first.clear(); + msg.first.resize(size); + receiver->port.readBytes(msg.first.data(), size); + msg.second.unlock(); + receiver->messageQueue.push(&msg); + } + } + } + } + + HardwareSerial &port; + freertos::Queue &messageQueue; + etl::string<4> magicNumberBuf; + const etl::string<2> magicNumber{"HX"}; + util::CircularBuffer buffer; + freertos::Task serialReceiverTask; + static const uint32_t stackDepth = 2048; +}; +} // namespace serial +} // namespace comm diff --git a/Firmware/src/Communication/Serial/SerialSender.cpp b/Firmware/src/Communication/Serial/SerialSender.cpp new file mode 100644 index 0000000..b687f31 --- /dev/null +++ b/Firmware/src/Communication/Serial/SerialSender.cpp @@ -0,0 +1,24 @@ +#include + +comm::serial::SerialSender::SerialSender(HardwareSerial &port, + UBaseType_t queueCapacity, + UBaseType_t priority, + BaseType_t coreID) + : port{port}, messages{queueCapacity}, SerialSenderTask{ + exec, "send serial data", + stackDepth, this, + priority, coreID} {} + +void comm::serial::SerialSender::exec(void *senderPtr) { + SerialSender *sender = static_cast(senderPtr); + freertos::sleep(20); // wait until Serial port has been initialized + while (true) { + if (!sender->port.availableForWrite()) { + continue; + } + auto message = sender->messages.pop(); + if (message.has_value()) { + sender->port.write(message.value().data(), message.value().size()); + } + } +} \ No newline at end of file diff --git a/Firmware/src/Communication/Serial/SerialSender.h b/Firmware/src/Communication/Serial/SerialSender.h new file mode 100644 index 0000000..1ed80c0 --- /dev/null +++ b/Firmware/src/Communication/Serial/SerialSender.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +namespace comm { +namespace serial { +class SerialSender { +public: + SerialSender(HardwareSerial &port, UBaseType_t queueCapacity, + UBaseType_t priority, BaseType_t coreID); + freertos::Queue> &getMessageQueue() { return messages; } + +private: + static void exec(void *senderPtr); + HardwareSerial &port; + freertos::Queue> messages; + freertos::Task SerialSenderTask; + static const uint32_t stackDepth = 2048; +}; +} // namespace serial +} // namespace comm diff --git a/Firmware/src/Messages/Message.h b/Firmware/src/Messages/Message.h new file mode 100644 index 0000000..7987868 --- /dev/null +++ b/Firmware/src/Messages/Message.h @@ -0,0 +1,12 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace message { +using Message = + etl::pair, + freertos::Mutex>; +} // namespace message