diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-09-04 11:25:08 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-09-04 11:25:08 +0300 |
commit | 6d7486602f47d18d8ff3c887f6253d470cf9711e (patch) | |
tree | 0c85f715a1751bebf9937c989f22c07afd5810c0 /src/Comms | |
parent | e49bf9991f74f5fd13935add8a19245431f2b2ee (diff) |
Refactored aux port support to handle multiple aux ports
Also stop analog input task on SAME5x build when preparing to load IAP
Diffstat (limited to 'src/Comms')
-rw-r--r-- | src/Comms/AuxDevice.cpp | 153 | ||||
-rw-r--r-- | src/Comms/AuxDevice.h | 42 |
2 files changed, 195 insertions, 0 deletions
diff --git a/src/Comms/AuxDevice.cpp b/src/Comms/AuxDevice.cpp new file mode 100644 index 00000000..52f6623d --- /dev/null +++ b/src/Comms/AuxDevice.cpp @@ -0,0 +1,153 @@ +/* + * AuxDevice.cpp + * + * Created on: 3 Sep 2020 + * Author: David + */ + +#include <Comms/AuxDevice.h> + +AuxDevice::AuxDevice() noexcept : uart(nullptr), seq(0), enabled(false), raw(true) +{ +} + +void AuxDevice::Init(UARTClass *p_uart) noexcept +{ + uart = p_uart; +# if SAME5x + uart->setInterruptPriority(NvicPriorityPanelDueUartRx, NvicPriorityPanelDueUartTx); +# else + uart->setInterruptPriority(NvicPriorityPanelDueUart); +#endif + mutex.Create("Aux"); +} + +void AuxDevice::Enable(uint32_t baudRate) noexcept +{ + if (uart != nullptr) + { + uart->begin(baudRate); + enabled = true; + } +} + +void AuxDevice::Disable() noexcept +{ + if (enabled) + { + uart->end(); + outStack.ReleaseAll(); + enabled = false; + } +} + +void AuxDevice::SendPanelDueMessage(const char* msg) noexcept +{ + if (enabled) + { + OutputBuffer *buf; + if (OutputBuffer::Allocate(buf)) + { + buf->copy("{\"message\":"); + buf->EncodeString(msg, false); + buf->cat("}\n"); + outStack.Push(buf); + Flush(); + } + } + +} + +void AuxDevice::AppendAuxReply(const char *msg, bool rawMessage) noexcept +{ + // Discard this response if either no aux device is attached or if the response is empty + if (msg[0] != 0 && enabled) + { + MutexLocker lock(mutex); + OutputBuffer *buf; + if (OutputBuffer::Allocate(buf)) + { + if (rawMessage || raw) + { + buf->copy(msg); + } + else + { + seq++; + buf->printf("{\"seq\":%" PRIu32 ",\"resp\":", seq); + buf->EncodeString(msg, true, false); + buf->cat("}\n"); + } + outStack.Push(buf); + } + } +} + +void AuxDevice::AppendAuxReply(OutputBuffer *reply, bool rawMessage) noexcept +{ + // Discard this response if either no aux device is attached or if the response is empty + if (reply == nullptr || reply->Length() == 0 || !enabled) + { + OutputBuffer::ReleaseAll(reply); + } + else + { + MutexLocker lock(mutex); + if (rawMessage || raw) + { + outStack.Push(reply); + } + else + { + OutputBuffer *buf; + if (OutputBuffer::Allocate(buf)) + { + seq++; + buf->printf("{\"seq\":%" PRIu32 ",\"resp\":", seq); + buf->EncodeReply(reply); + buf->cat("}\n"); + outStack.Push(buf); + } + else + { + OutputBuffer::ReleaseAll(reply); + } + } + } +} + +bool AuxDevice::Flush() noexcept +{ + bool hasMore = !outStack.IsEmpty(); + if (hasMore) + { + MutexLocker lock(mutex); + OutputBuffer *auxOutputBuffer = outStack.GetFirstItem(); + if (auxOutputBuffer == nullptr) + { + (void)outStack.Pop(); + } + else if (!enabled) + { + OutputBuffer::ReleaseAll(auxOutputBuffer); + (void)outStack.Pop(); + } + else + { + const size_t bytesToWrite = min<size_t>(uart->canWrite(), auxOutputBuffer->BytesLeft()); + if (bytesToWrite > 0) + { + uart->write(auxOutputBuffer->Read(bytesToWrite), bytesToWrite); + } + + if (auxOutputBuffer->BytesLeft() == 0) + { + outStack.ReleaseFirstItem(); + } + } + hasMore = !outStack.IsEmpty(); + } + return hasMore; +} + +// End diff --git a/src/Comms/AuxDevice.h b/src/Comms/AuxDevice.h new file mode 100644 index 00000000..32b74fb1 --- /dev/null +++ b/src/Comms/AuxDevice.h @@ -0,0 +1,42 @@ +/* + * AuxDevice.h + * + * Created on: 3 Sep 2020 + * Author: David + */ + +#ifndef SRC_COMMS_AUXDEVICE_H_ +#define SRC_COMMS_AUXDEVICE_H_ + +#include <RepRapFirmware.h> +#include <OutputMemory.h> +#include <RTOSIface/RTOSIface.h> + +class AuxDevice +{ +public: + AuxDevice() noexcept; + + void Init(UARTClass *p_uart) noexcept; + bool IsEnabled() const noexcept { return enabled; } + void Enable(uint32_t baudRate) noexcept; + void Disable() noexcept; + + bool IsRaw() const noexcept { return raw; } + void SetRaw(bool p_raw) { raw = p_raw; } + + void SendPanelDueMessage(const char* msg) noexcept; + void AppendAuxReply(const char *msg, bool rawMessage) noexcept; + void AppendAuxReply(OutputBuffer *reply, bool rawMessage) noexcept; + bool Flush() noexcept; + +private: + UARTClass *uart; + volatile OutputStack outStack; + Mutex mutex; + uint32_t seq; // sequence number for output + bool enabled; // is it initialised and running? + bool raw; // true if device is in raw mode +}; + +#endif /* SRC_COMMS_AUXDEVICE_H_ */ |