forked from magao-x/MagAOX
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added fsm telemetry app connecting via socket * Cleaned up logging across all fsm header files. Added ADC & DAC query commands. * Added INDI params to send DACs. Fixed state progression. * Adding voltage to dac & angles to actuator displacement conversion. Diagrams for the INDI commands. * Added shmim commands. Made block diagrams for the INDI & shmim logic. * Documentation * Added toggle between indi & shmim * Added ADC 'current' params that show the ADC values queried on connection and after a DAC value update. * Added status.query INDI param to query 'adc' or 'dac' values. * WIP test writing
- Loading branch information
Showing
25 changed files
with
6,537 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#pragma once | ||
|
||
#include <stdarg.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
|
||
class IUart | ||
{ | ||
public: | ||
IUart() { } | ||
virtual ~IUart() { } | ||
|
||
static const bool OddParity = true; | ||
static const bool NoParity = false; | ||
static const bool IUartOK = 0x00; | ||
static const bool UseRTSCTS = true; | ||
static const bool NoRTSCTS = false; | ||
|
||
|
||
//All the following pinout functions are very hardware & device dependant, so they are declared in another class to preserve the abstraction | ||
//virtual int init() { return(InitOK); } //note: this functiuon usually gets overloaded with different params, so it's no longer virtual anyway - probably not an issue, since it usually gets called from code with the full object, not just the base class. | ||
//~ virtual bool dataready() { printf("\nIUart::dataready() stub!\n"); return(false); } | ||
//~ virtual char getcqq() { printf("\nIUart::getcqq() stub!\n"); return('\0'); } | ||
//~ virtual char putcqq(char c) { printf("\nIUart::putcqq() stub!\n"); return('\0'); } | ||
//~ virtual void flushoutput() { printf("\nIUart::flushoutput() stub!\n"); } | ||
//~ virtual void purgeinput() { printf("\nIUart::purgeinput() stub!\n"); } | ||
//~ virtual bool isopen() { printf("\nIUart::isopen() stub!\n"); return(false); } | ||
virtual bool dataready() const = 0; | ||
virtual char getcqq() = 0; | ||
virtual char putcqq(char c) = 0; | ||
virtual void flushoutput() = 0; | ||
virtual void purgeinput() = 0; | ||
virtual bool isopen() const = 0; | ||
|
||
void puts(const char* s, const size_t len) | ||
{ | ||
for (size_t i = 0; i < len; i++) | ||
{ | ||
if ('\0' == s[i]) { break; } | ||
|
||
putcqq(s[i]); | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
allall: all | ||
|
||
debug_opt: all | ||
debug_opt: CXXFLAGS += -g | ||
|
||
OTHER_HEADERS= | ||
TARGET=fsmCtrl | ||
include ../../Make/magAOXApp.mk | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,317 @@ | ||
// | ||
/// Copyright (c)2007 by Franks Development, LLC | ||
// | ||
// This software is copyrighted by and is the sole property of Franks | ||
// Development, LLC. All rights, title, ownership, or other interests | ||
// in the software remain the property of Franks Development, LLC. This | ||
// software may only be used in accordance with the corresponding | ||
// license agreement. Any unauthorized use, duplication, transmission, | ||
// distribution, or disclosure of this software is expressly forbidden. | ||
// | ||
// This Copyright notice may not be removed or modified without prior | ||
// written consent of Franks Development, LLC. | ||
// | ||
// Franks Development, LLC. reserves the right to modify this software | ||
// without notice. | ||
// | ||
// Franks Development, LLC [email protected] | ||
// 500 N. Bahamas Dr. #101 http://www.franks-development.com | ||
// Tucson, AZ 85710 | ||
// USA | ||
// | ||
|
||
#pragma once | ||
|
||
#include <stdio.h> | ||
#include <stdarg.h> | ||
#include <stdint.h> | ||
|
||
#include <sstream> // for stringstreams | ||
|
||
#include "IUart.h" | ||
|
||
#include "iPacket.hpp" | ||
|
||
#include "cGraphPacket.hpp" | ||
#include "fsmCommands.hpp" | ||
|
||
namespace MagAOX | ||
{ | ||
namespace app | ||
{ | ||
|
||
struct BinaryUartCallbacks | ||
{ | ||
BinaryUartCallbacks() { } | ||
virtual ~BinaryUartCallbacks() { } | ||
|
||
//Malformed/corrupted packet handler: | ||
virtual void InvalidPacket(const uint8_t* Buffer, const size_t& BufferLen) { } | ||
|
||
//Packet with no matching command handler: | ||
virtual void UnHandledPacket(const IPacket* Packet, const size_t& PacketLen) { } | ||
|
||
//In case we need to look at every packet that goes by... | ||
virtual void EveryPacket(const IPacket* Packet, const size_t& PacketLen) { } | ||
|
||
//Seems like someone, sometime might wanna handle this... | ||
virtual void BufferOverflow(const size_t& BufferLen) { } | ||
}; | ||
|
||
|
||
struct BinaryUart | ||
{ | ||
//Default values | ||
static const uint64_t RxCountInit = 0; | ||
static const uint64_t PacketStartInit = 0; | ||
static const uint64_t PacketLenInit = 0; | ||
static const bool InPacketInit = false; | ||
static const bool debugDefault = false; | ||
static const char EmptyBufferChar = '\0'; | ||
|
||
static const size_t RxBufferLenBytes = 4096; | ||
static const size_t TxBufferLenBytes = 4096; | ||
uint8_t RxBuffer[RxBufferLenBytes]; //This is where the received characters go while we are building a line up from the input | ||
uint16_t RxCount; | ||
IUart& Pinout; | ||
IPacket& Packet; | ||
BinaryUartCallbacks& Callbacks; | ||
bool debug; | ||
bool InPacket; | ||
size_t PacketStart; | ||
size_t PacketLen; | ||
size_t packetEnd = 0; | ||
//~ const void* Argument; | ||
uint64_t SerialNum; | ||
static const uint64_t InvalidSerialNumber = 0xFFFFFFFFFFFFFFFFULL; | ||
|
||
BinaryUart(struct IUart& pinout, struct IPacket& packet, struct BinaryUartCallbacks& callbacks, const uint64_t serialnum = InvalidSerialNumber) | ||
: | ||
RxCount(RxCountInit), | ||
Pinout(pinout), | ||
Packet(packet), | ||
Callbacks(callbacks), | ||
debug(debugDefault), | ||
//~ debug(true), | ||
InPacket(InPacketInit), | ||
PacketStart(PacketStartInit), | ||
PacketLen(PacketLenInit), | ||
SerialNum(serialnum) | ||
|
||
{ | ||
Init(serialnum); | ||
} | ||
|
||
void Debug(bool dbg) | ||
{ | ||
debug = dbg; | ||
} | ||
|
||
const uint8_t* GetRxBuffer() const | ||
{ | ||
return RxBuffer; | ||
} | ||
|
||
int Init(uint64_t serialnum) | ||
{ | ||
SerialNum = serialnum; | ||
RxCount = RxCountInit; | ||
PacketStart = PacketStartInit; | ||
PacketLen = PacketLenInit; | ||
InPacket = InPacketInit; | ||
memset(RxBuffer, EmptyBufferChar, RxBufferLenBytes); | ||
|
||
std::ostringstream oss; | ||
oss << "Binary Uart: Init(PktH " << Packet.HeaderLen() << ", PktF " << Packet.FooterLen() << ")."; | ||
MagAOXAppT::log<text_log>(oss.str()); | ||
|
||
return(0); | ||
} | ||
|
||
bool Process(MagAOX::app::PZTQuery* pztQuery) | ||
{ | ||
//New char? | ||
if ( !(Pinout.dataready()) ) { return(false); } | ||
|
||
//pull it off the hardware | ||
uint8_t c = Pinout.getcqq(); | ||
|
||
ProcessByte(c); | ||
CheckPacketStart(); | ||
CheckPacketEnd(pztQuery); | ||
|
||
return(true); //We just want to know if there's chars in the buffer to put threads to sleep or not... | ||
} | ||
|
||
void ProcessByte(const char c) | ||
{ | ||
//Put the current character into the buffer | ||
if (RxCount < RxBufferLenBytes) | ||
{ | ||
RxCount++; | ||
RxBuffer[RxCount - 1] = c; | ||
} | ||
else | ||
{ | ||
if (debug) | ||
{ | ||
std::ostringstream oss; | ||
oss << "BinaryUart: Buffer(" << RxBuffer <<") overflow; this packet will not fit (" << RxCount << "b), flushing buffer."; | ||
MagAOXAppT::log<software_debug>({__FILE__, __LINE__, oss.str()}); | ||
} | ||
|
||
Callbacks.BufferOverflow(RxCount); | ||
|
||
Init(SerialNum); | ||
} | ||
} | ||
|
||
void CheckPacketStart() | ||
{ | ||
//Packet Start? | ||
if ( (!InPacket) && (RxCount >= Packet.HeaderLen()) ) | ||
{ | ||
if (Packet.FindPacketStart(RxBuffer, RxCount, PacketStart)) //This is wasteful, we really only need to look at the 4 newest bytes every time... | ||
{ | ||
if (debug) { MagAOXAppT::log<software_debug>({__FILE__, __LINE__, "BinaryUart: Packet start detected! Buffering."}); } | ||
|
||
InPacket = true; | ||
} | ||
} | ||
} | ||
|
||
bool CheckPacketEnd(MagAOX::app::PZTQuery* pztQuery) | ||
{ | ||
packetEnd = 0; | ||
bool Processed = false; | ||
|
||
if (!InPacket || RxCount < (Packet.HeaderLen() + Packet.FooterLen())) | ||
return false; | ||
|
||
//This is wasteful, we really only need to look at the 4 newest bytes every time... | ||
if (!Packet.FindPacketEnd(RxBuffer, RxCount, packetEnd)) { | ||
if (debug) { | ||
MagAOXAppT::log<software_debug>({__FILE__, __LINE__, "BinaryUart: Still waiting for packet end..."}); | ||
} | ||
return false; | ||
} | ||
|
||
if (debug) { | ||
MagAOXAppT::log<software_debug>({__FILE__, __LINE__, "BinaryUart: Packet end detected; Looking for matching packet handlers."}); | ||
} | ||
|
||
const size_t payloadLen = Packet.PayloadLen(RxBuffer, RxCount, PacketStart); | ||
|
||
if (RxCount < payloadLen + Packet.HeaderLen() + Packet.FooterLen()) | ||
{ | ||
if ( (payloadLen > RxBufferLenBytes) || (payloadLen > Packet.MaxPayloadLength()) ) | ||
{ | ||
if (debug) | ||
{ | ||
std::ostringstream oss; | ||
oss << "BinaryUart: Short packet (" << RxCount << " bytes) with unrealistic payload len; ignoring corrupted packet (should have been header() + payload(" << payloadLen << ") + footer()."; | ||
MagAOXAppT::log<software_debug>({__FILE__, __LINE__, oss.str()}); | ||
} | ||
|
||
Callbacks.InvalidPacket(reinterpret_cast<uint8_t*>(RxBuffer), RxCount); | ||
|
||
Init(SerialNum); | ||
|
||
return false; | ||
} | ||
else | ||
{ | ||
if (debug) | ||
{ | ||
std::ostringstream oss; | ||
oss << "BinaryUart: Short packet (" << RxCount << " bytes); we'll assume the packet footer was part of the payload data and keep searching for the packet end (should have been header() + payload(" << payloadLen << ") + footer()."; | ||
MagAOXAppT::log<software_debug>({__FILE__, __LINE__, oss.str()}); | ||
} | ||
|
||
return false; | ||
} | ||
} | ||
|
||
if (Packet.IsValid(RxBuffer, RxCount, PacketStart)) | ||
{ | ||
if ( (SerialNum == InvalidSerialNumber) || (SerialNum == Packet.SerialNum() ) ) | ||
{ | ||
|
||
//strip the part of the line with the arguments to this command (chars following command) for compatibility with the parsing code, the "params" officially start with the s/n | ||
const char* Params = reinterpret_cast<char*>(&(RxBuffer[PacketStart + Packet.PayloadOffset()])); | ||
|
||
//call the actual command | ||
pztQuery->processReply(Params, payloadLen); | ||
|
||
Processed = true; | ||
} | ||
else | ||
{ | ||
if (debug) | ||
{ | ||
std::ostringstream oss; | ||
oss << "BinaryUart: Packet received, but SerialNumber comparison failed (expected: 0x" << SerialNum << "; got: 0x" << Packet.SerialNum() << ")."; | ||
MagAOXAppT::log<software_debug>({__FILE__, __LINE__, oss.str()}); | ||
} | ||
|
||
Callbacks.UnHandledPacket(reinterpret_cast<IPacket*>(&RxBuffer[PacketStart]), packetEnd - PacketStart); | ||
} | ||
|
||
//Now just let the user do whatever they want with it... | ||
Callbacks.EveryPacket(reinterpret_cast<IPacket*>(&RxBuffer[PacketStart]), packetEnd - PacketStart); | ||
} | ||
else | ||
{ | ||
if (debug) { MagAOXAppT::log<software_debug>({__FILE__, __LINE__, "BinaryUart: Packet received, but invalid."}); } | ||
|
||
Callbacks.InvalidPacket(reinterpret_cast<uint8_t*>(RxBuffer), RxCount); | ||
} | ||
|
||
InPacket = false; | ||
|
||
if (RxCount > (packetEnd + 4) ) | ||
{ | ||
size_t pos = 0; | ||
size_t clr = 0; | ||
for (; pos < (RxCount - (packetEnd + 4)); pos++) | ||
{ | ||
RxBuffer[pos] = RxBuffer[(packetEnd + 4) + pos]; | ||
} | ||
for (clr = pos; clr < RxCount; clr++) | ||
{ | ||
RxBuffer[clr] = 0; | ||
} | ||
RxCount = pos; | ||
} | ||
else | ||
{ | ||
Init(SerialNum); | ||
} | ||
|
||
return Processed; | ||
} | ||
|
||
void TxBinaryPacket(const uint16_t PayloadType, const void* PayloadData, const size_t PayloadLen) const | ||
{ | ||
uint8_t TxBuffer[TxBufferLenBytes]; | ||
size_t PacketLen = Packet.MakePacket(TxBuffer, TxBufferLenBytes, PayloadData, PayloadType, PayloadLen); | ||
|
||
std::ostringstream oss; | ||
oss << "Packet length: " << PacketLen; | ||
MagAOXAppT::log<text_log>(oss.str()); | ||
|
||
for (size_t i = 0; i < PacketLen; i++) { Pinout.putcqq(TxBuffer[i]); } | ||
|
||
// Log packet sent | ||
oss.str(""); | ||
oss << "Binary Uart: Sending packet(" << PayloadType << ", " << PayloadLen << "): "; | ||
MagAOXAppT::log<text_log>(oss.str()); | ||
oss.str(""); | ||
for(size_t i = 0; i < PacketLen; i++) { oss << std::setw(2) << std::setfill('0') << std::hex << static_cast<unsigned>(TxBuffer[i]) << ":"; } | ||
MagAOXAppT::log<text_log>(oss.str()); | ||
|
||
} | ||
}; | ||
|
||
} //namespace app | ||
} //namespace MagAOX |
Oops, something went wrong.