/************************************************************************************
 * This file was auto-generated by CIDEA                           .                *
 * Please do not modify the contents of this file manually.                         *
 ***********************************************************************************/


#include "cubeacp.h"

uint16_t CUBEACP_GetTlmLen(CUBEACP_Telemetry_t tlm)
{
    switch(tlm)
    {
        case AcpLoopState:
            return 3;
        case ActuatorCmd:
            return 12;
        case AdcsConfig:
            return 504;
        case AdcsExecTimes:
            return 8;
        case AdcsMeasure:
            return 72;
        case AdcsMiscCurrents:
            return 6;
        case AdcsPower:
            return 3;
        case AdcsPowerMeasure:
            return 38;
        case AdcsState:
            return 54;
        case AdcsSystemConfig:
            return 173;
        case AdcsTemperatures1:
            return 6;
        case AdcsTemperatures2:
            return 6;
        case Asgp4KepTle:
            return 33;
        case ASgp4Params:
            return 30;
        case CmdAttitude:
            return 6;
        case CmdTrackingTarget:
            return 12;
        case CoarseSunVec:
            return 6;
        case ConversionProgress:
            return 3;
        case CssConfig:
            return 21;
        case CubeACPState:
            return 1;
        case CubeControlCurrents:
            return 6;
        case CubeSense1Currents:
            return 4;
        case CubeSense2Currents:
            return 4;
        case CubeSenseConfig:
            return 112;
        case CurrentAdcsState:
            return 6;
        case CurrentAdcsState2:
            return 6;
        case DetumbleParams:
            return 14;
        case EstimAttitude:
            return 6;
        case EstimData:
            return 42;
        case EstimGyroBias:
            return 6;
        case EstimParams:
            return 31;
        case EstimQuaternion:
            return 6;
        case EstimRates:
            return 6;
        case FineEstimRates:
            return 6;
        case FineSunVec:
            return 6;
        case GyroConfig:
            return 10;
        case ImageSaveStatus:
            return 2;
        case InertialPointReference:
            return 6;
        case InnovationVec:
            return 6;
        case LogSdConfig1:
            return 13;
        case LogSdConfig2:
            return 13;
        case LogUartConfig:
            return 12;
        case MagConfig:
            return 30;
        case MagField:
            return 6;
        case MagRaw2:
            return 6;
        case MagtorqConfig:
            return 3;
        case MagTorquerCmd:
            return 6;
        case ModelMagVec:
            return 6;
        case ModelSunVec:
            return 6;
        case MoI:
            return 24;
        case NadirVec:
            return 6;
        case OrbitParameters:
            return 64;
        case PositionECEF:
            return 6;
        case PositionECI:
            return 6;
        case PositionLLH:
            return 6;
        case QuaternionCovar:
            return 6;
        case QuaternionErrVec:
            return 6;
        case RateCovar:
            return 6;
        case RateSensor:
            return 6;
        case RawCam1Sens:
            return 6;
        case RawCam2Sens:
            return 6;
        case RawCss1:
            return 6;
        case RawCss2:
            return 6;
        case RawGPS:
            return 36;
        case RawGpsStatus:
            return 6;
        case RawGpsTime:
            return 6;
        case RawGpsX:
            return 6;
        case RawGpsY:
            return 6;
        case RawGpsZ:
            return 6;
        case RawMagnetometer:
            return 6;
        case RawRate:
            return 6;
        case RawSensor:
            return 34;
        case RawStarTracker:
            return 54;
        case RedMagConfig:
            return 30;
        case RWheelParams:
            return 13;
        case SpeedCmd:
            return 6;
        case Star1Body:
            return 6;
        case Star1Orbit:
            return 6;
        case Star1Raw:
            return 6;
        case Star2Body:
            return 6;
        case Star2Orbit:
            return 6;
        case Star2Raw:
            return 6;
        case Star3Body:
            return 6;
        case Star3Orbit:
            return 6;
        case Star3Raw:
            return 6;
        case StarConfig:
            return 53;
        case StarEstimQ:
            return 6;
        case StarEstimRate:
            return 6;
        case StarMagnitude:
            return 6;
        case StarPerformance1:
            return 6;
        case StarPerformance2:
            return 6;
        case StarTiming:
            return 6;
        case TrackingParams:
            return 13;
        case UserConEstParams:
            return 96;
        case VelocityECI:
            return 6;
        case WheelConfig:
            return 4;
        case WheelCurrents:
            return 6;
        case WheelSpeed:
            return 6;
        case YWheelParams:
            return 20;
        default:
            return -1;
    }
}
CUBEADCS_Result_t CUBEACP_ExtractAcpLoopStateTlm(uint8_t* rxBuffer, CUBEACP_AcpLoopState_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->timeSinceLoopStart = *( (U16*) (rxBuffer + 0) );

    enumVal = rxBuffer[2];
    returnVal->currentExecutionPoint = (CUBEACP_ExecutionWaypoints_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractActuatorCmdTlm(uint8_t* rxBuffer, CUBEACP_ActuatorCmd_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->torquerCmdX = *( (S16*) (rxBuffer + 0) );

    returnVal->torquerCmdY = *( (S16*) (rxBuffer + 2) );

    returnVal->torquerCmdZ = *( (S16*) (rxBuffer + 4) );

    returnVal->speedCmdX = *( (S16*) (rxBuffer + 6) );

    returnVal->speedCmdY = *( (S16*) (rxBuffer + 8) );

    returnVal->speedCmdZ = *( (S16*) (rxBuffer + 10) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawXRateOffset;
    S16 rawYRateOffset;
    S16 rawZRateOffset;
    U8 rawCss1Scale;
    U8 rawCss2Scale;
    U8 rawCss3Scale;
    U8 rawCss4Scale;
    U8 rawCss5Scale;
    U8 rawCss6Scale;
    U8 rawCss7Scale;
    U8 rawCss8Scale;
    U8 rawCss9Scale;
    U8 rawCss10Scale;
    S16 rawCam1Angle1;
    S16 rawCam1Angle2;
    S16 rawCam1Angle3;
    U16 rawCam1BoreX;
    U16 rawCam1BoreY;
    S16 rawCam2Angle1;
    S16 rawCam2Angle2;
    S16 rawCam2Angle3;
    U16 rawCam2BoreX;
    U16 rawCam2BoreY;
    S16 rawMagmAngle1;
    S16 rawMagmAngle2;
    S16 rawMagmAngle3;
    S16 rawMagmOffset1;
    S16 rawMagmOffset2;
    S16 rawMagmOffset3;
    S16 rawMagmSens11;
    S16 rawMagmSens22;
    S16 rawMagmSens33;
    S16 rawMagmSens12;
    S16 rawMagmSens13;
    S16 rawMagmSens21;
    S16 rawMagmSens23;
    S16 rawMagmSens31;
    S16 rawMagmSens32;
    S16 rawMredAngle1;
    S16 rawMredAngle2;
    S16 rawMredAngle3;
    S16 rawMredOffset1;
    S16 rawMredOffset2;
    S16 rawMredOffset3;
    S16 rawMredSens11;
    S16 rawMredSens22;
    S16 rawMredSens33;
    S16 rawMredSens12;
    S16 rawMredSens13;
    S16 rawMredSens21;
    S16 rawMredSens23;
    S16 rawMredSens31;
    S16 rawMredSens32;
    S16 rawStarAngle1;
    S16 rawStarAngle2;
    S16 rawStarAngle3;
    U8 rawStarErrorMargin;
    U8 rawStarTrackingMargin;
    U8 rawStarValidationMargin;
    U8 rawStarSearchWidth;
    S16 rawwy_ref;
    U16 rawAInclCoeff;
    U16 rawARaanCoeff;
    U16 rawAEccCoeff;
    U16 rawAArgPerCoeff;
    U16 rawATimeCoeff;
    U16 rawAPosCoeff;
    U8 rawAsgp4MaxPosError;
    S32 rawAsgp4Xp;
    S32 rawAsgp4Yp;
    U8 rawAsgp4PosSdTh;
    U8 rawAsgp4VelSdTh;
    U8 rawAsgp4TimeGain;
    U8 rawAsgp4MaxLag;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->magtorq1 = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[1];
    returnVal->magtorq2 = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[2];
    returnVal->magtorq3 = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[3];
    returnVal->rW1Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[4];
    returnVal->rW2Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[5];
    returnVal->rW3Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[6];
    returnVal->rW4Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[7];
    returnVal->gyro1Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[8];
    returnVal->gyro2Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[9];
    returnVal->gyro3Conf = (CUBEACP_AxisSelect_t) enumVal;

    rawXRateOffset = *( (S16*) (rxBuffer + 10) );
    returnVal->xRateOffset = rawXRateOffset*0.001;

    rawYRateOffset = *( (S16*) (rxBuffer + 12) );
    returnVal->yRateOffset = rawYRateOffset*0.001;

    rawZRateOffset = *( (S16*) (rxBuffer + 14) );
    returnVal->zRateOffset = rawZRateOffset*0.001;

    returnVal->rateSensorMult = *( (U8*) (rxBuffer + 16) );

    enumVal = rxBuffer[17];
    returnVal->css1Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[18];
    returnVal->css2Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[19];
    returnVal->css3Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[20];
    returnVal->css4Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[21];
    returnVal->css5Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[22];
    returnVal->css6Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[23];
    returnVal->css7Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[24];
    returnVal->css8Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[25];
    returnVal->css9Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[26];
    returnVal->css10Conf = (CUBEACP_AxisSelect_t) enumVal;

    rawCss1Scale = *( (U8*) (rxBuffer + 27) );
    returnVal->css1Scale = rawCss1Scale*0.01;

    rawCss2Scale = *( (U8*) (rxBuffer + 28) );
    returnVal->css2Scale = rawCss2Scale*0.01;

    rawCss3Scale = *( (U8*) (rxBuffer + 29) );
    returnVal->css3Scale = rawCss3Scale*0.01;

    rawCss4Scale = *( (U8*) (rxBuffer + 30) );
    returnVal->css4Scale = rawCss4Scale*0.01;

    rawCss5Scale = *( (U8*) (rxBuffer + 31) );
    returnVal->css5Scale = rawCss5Scale*0.01;

    rawCss6Scale = *( (U8*) (rxBuffer + 32) );
    returnVal->css6Scale = rawCss6Scale*0.01;

    rawCss7Scale = *( (U8*) (rxBuffer + 33) );
    returnVal->css7Scale = rawCss7Scale*0.01;

    rawCss8Scale = *( (U8*) (rxBuffer + 34) );
    returnVal->css8Scale = rawCss8Scale*0.01;

    rawCss9Scale = *( (U8*) (rxBuffer + 35) );
    returnVal->css9Scale = rawCss9Scale*0.01;

    rawCss10Scale = *( (U8*) (rxBuffer + 36) );
    returnVal->css10Scale = rawCss10Scale*0.01;

    returnVal->cssMinimum = *( (U8*) (rxBuffer + 37) );

    rawCam1Angle1 = *( (S16*) (rxBuffer + 38) );
    returnVal->cam1Angle1 = rawCam1Angle1*0.01;

    rawCam1Angle2 = *( (S16*) (rxBuffer + 40) );
    returnVal->cam1Angle2 = rawCam1Angle2*0.01;

    rawCam1Angle3 = *( (S16*) (rxBuffer + 42) );
    returnVal->cam1Angle3 = rawCam1Angle3*0.01;

    returnVal->cam1Threshold = *( (U8*) (rxBuffer + 44) );

    returnVal->cam1AutoAdj = (rxBuffer[45] & 0x01) >> 0;


    returnVal->cam1Exposure = *( (U16*) (rxBuffer + 46) );

    rawCam1BoreX = *( (U16*) (rxBuffer + 48) );
    returnVal->cam1BoreX = rawCam1BoreX*0.01;

    rawCam1BoreY = *( (U16*) (rxBuffer + 50) );
    returnVal->cam1BoreY = rawCam1BoreY*0.01;

    rawCam2Angle1 = *( (S16*) (rxBuffer + 52) );
    returnVal->cam2Angle1 = rawCam2Angle1*0.01;

    rawCam2Angle2 = *( (S16*) (rxBuffer + 54) );
    returnVal->cam2Angle2 = rawCam2Angle2*0.01;

    rawCam2Angle3 = *( (S16*) (rxBuffer + 56) );
    returnVal->cam2Angle3 = rawCam2Angle3*0.01;

    returnVal->cam2Threshold = *( (U8*) (rxBuffer + 58) );

    returnVal->cam2AutoAdj = (rxBuffer[59] & 0x01) >> 0;


    returnVal->cam2Exposure = *( (U16*) (rxBuffer + 60) );

    rawCam2BoreX = *( (U16*) (rxBuffer + 62) );
    returnVal->cam2BoreX = rawCam2BoreX*0.01;

    rawCam2BoreY = *( (U16*) (rxBuffer + 64) );
    returnVal->cam2BoreY = rawCam2BoreY*0.01;

    returnVal->nadirMaxDeviationPercentage = *( (U8*) (rxBuffer + 66) );

    returnVal->nadirMaxBadEdges = *( (U8*) (rxBuffer + 67) );

    returnVal->nadirMaxRadius = *( (U8*) (rxBuffer + 68) );

    returnVal->nadirMinRadius = *( (U8*) (rxBuffer + 69) );

    returnVal->cam1MaskArea1Xmin = *( (U16*) (rxBuffer + 70) );

    returnVal->cam1MaskArea1Xmax = *( (U16*) (rxBuffer + 72) );

    returnVal->cam1MaskArea1Ymin = *( (U16*) (rxBuffer + 74) );

    returnVal->cam1MaskArea1Ymax = *( (U16*) (rxBuffer + 76) );

    returnVal->cam1MaskArea2Xmin = *( (U16*) (rxBuffer + 78) );

    returnVal->cam1MaskArea2Xmax = *( (U16*) (rxBuffer + 80) );

    returnVal->cam1MaskArea2Ymin = *( (U16*) (rxBuffer + 82) );

    returnVal->cam1MaskArea2Ymax = *( (U16*) (rxBuffer + 84) );

    returnVal->cam1MaskArea3Xmin = *( (U16*) (rxBuffer + 86) );

    returnVal->cam1MaskArea3Xmax = *( (U16*) (rxBuffer + 88) );

    returnVal->cam1MaskArea3Ymin = *( (U16*) (rxBuffer + 90) );

    returnVal->cam1MaskArea3Ymax = *( (U16*) (rxBuffer + 92) );

    returnVal->cam1MaskArea4Xmin = *( (U16*) (rxBuffer + 94) );

    returnVal->cam1MaskArea4Xmax = *( (U16*) (rxBuffer + 96) );

    returnVal->cam1MaskArea4Ymin = *( (U16*) (rxBuffer + 98) );

    returnVal->cam1MaskArea4Ymax = *( (U16*) (rxBuffer + 100) );

    returnVal->cam1MaskArea5Xmin = *( (U16*) (rxBuffer + 102) );

    returnVal->cam1MaskArea5Xmax = *( (U16*) (rxBuffer + 104) );

    returnVal->cam1MaskArea5Ymin = *( (U16*) (rxBuffer + 106) );

    returnVal->cam1MaskArea5Ymax = *( (U16*) (rxBuffer + 108) );

    returnVal->cam2MaskArea1Xmin = *( (U16*) (rxBuffer + 110) );

    returnVal->cam2MaskArea1Xmax = *( (U16*) (rxBuffer + 112) );

    returnVal->cam2MaskArea1Ymin = *( (U16*) (rxBuffer + 114) );

    returnVal->cam2MaskArea1Ymax = *( (U16*) (rxBuffer + 116) );

    returnVal->cam2MaskArea2Xmin = *( (U16*) (rxBuffer + 118) );

    returnVal->cam2MaskArea2Xmax = *( (U16*) (rxBuffer + 120) );

    returnVal->cam2MaskArea2Ymin = *( (U16*) (rxBuffer + 122) );

    returnVal->cam2MaskArea2Ymax = *( (U16*) (rxBuffer + 124) );

    returnVal->cam2MaskArea3Xmin = *( (U16*) (rxBuffer + 126) );

    returnVal->cam2MaskArea3Xmax = *( (U16*) (rxBuffer + 128) );

    returnVal->cam2MaskArea3Ymin = *( (U16*) (rxBuffer + 130) );

    returnVal->cam2MaskArea3Ymax = *( (U16*) (rxBuffer + 132) );

    returnVal->cam2MaskArea4Xmin = *( (U16*) (rxBuffer + 134) );

    returnVal->cam2MaskArea4Xmax = *( (U16*) (rxBuffer + 136) );

    returnVal->cam2MaskArea4Ymin = *( (U16*) (rxBuffer + 138) );

    returnVal->cam2MaskArea4Ymax = *( (U16*) (rxBuffer + 140) );

    returnVal->cam2MaskArea5Xmin = *( (U16*) (rxBuffer + 142) );

    returnVal->cam2MaskArea5Xmax = *( (U16*) (rxBuffer + 144) );

    returnVal->cam2MaskArea5Ymin = *( (U16*) (rxBuffer + 146) );

    returnVal->cam2MaskArea5Ymax = *( (U16*) (rxBuffer + 148) );

    rawMagmAngle1 = *( (S16*) (rxBuffer + 150) );
    returnVal->magmAngle1 = rawMagmAngle1*0.01;

    rawMagmAngle2 = *( (S16*) (rxBuffer + 152) );
    returnVal->magmAngle2 = rawMagmAngle2*0.01;

    rawMagmAngle3 = *( (S16*) (rxBuffer + 154) );
    returnVal->magmAngle3 = rawMagmAngle3*0.01;

    rawMagmOffset1 = *( (S16*) (rxBuffer + 156) );
    returnVal->magmOffset1 = rawMagmOffset1*0.001;

    rawMagmOffset2 = *( (S16*) (rxBuffer + 158) );
    returnVal->magmOffset2 = rawMagmOffset2*0.001;

    rawMagmOffset3 = *( (S16*) (rxBuffer + 160) );
    returnVal->magmOffset3 = rawMagmOffset3*0.001;

    rawMagmSens11 = *( (S16*) (rxBuffer + 162) );
    returnVal->magmSens11 = rawMagmSens11*0.001;

    rawMagmSens22 = *( (S16*) (rxBuffer + 164) );
    returnVal->magmSens22 = rawMagmSens22*0.001;

    rawMagmSens33 = *( (S16*) (rxBuffer + 166) );
    returnVal->magmSens33 = rawMagmSens33*0.001;

    rawMagmSens12 = *( (S16*) (rxBuffer + 168) );
    returnVal->magmSens12 = rawMagmSens12*0.001;

    rawMagmSens13 = *( (S16*) (rxBuffer + 170) );
    returnVal->magmSens13 = rawMagmSens13*0.001;

    rawMagmSens21 = *( (S16*) (rxBuffer + 172) );
    returnVal->magmSens21 = rawMagmSens21*0.001;

    rawMagmSens23 = *( (S16*) (rxBuffer + 174) );
    returnVal->magmSens23 = rawMagmSens23*0.001;

    rawMagmSens31 = *( (S16*) (rxBuffer + 176) );
    returnVal->magmSens31 = rawMagmSens31*0.001;

    rawMagmSens32 = *( (S16*) (rxBuffer + 178) );
    returnVal->magmSens32 = rawMagmSens32*0.001;

    rawMredAngle1 = *( (S16*) (rxBuffer + 180) );
    returnVal->mredAngle1 = rawMredAngle1*0.01;

    rawMredAngle2 = *( (S16*) (rxBuffer + 182) );
    returnVal->mredAngle2 = rawMredAngle2*0.01;

    rawMredAngle3 = *( (S16*) (rxBuffer + 184) );
    returnVal->mredAngle3 = rawMredAngle3*0.01;

    rawMredOffset1 = *( (S16*) (rxBuffer + 186) );
    returnVal->mredOffset1 = rawMredOffset1*0.001;

    rawMredOffset2 = *( (S16*) (rxBuffer + 188) );
    returnVal->mredOffset2 = rawMredOffset2*0.001;

    rawMredOffset3 = *( (S16*) (rxBuffer + 190) );
    returnVal->mredOffset3 = rawMredOffset3*0.001;

    rawMredSens11 = *( (S16*) (rxBuffer + 192) );
    returnVal->mredSens11 = rawMredSens11*0.001;

    rawMredSens22 = *( (S16*) (rxBuffer + 194) );
    returnVal->mredSens22 = rawMredSens22*0.001;

    rawMredSens33 = *( (S16*) (rxBuffer + 196) );
    returnVal->mredSens33 = rawMredSens33*0.001;

    rawMredSens12 = *( (S16*) (rxBuffer + 198) );
    returnVal->mredSens12 = rawMredSens12*0.001;

    rawMredSens13 = *( (S16*) (rxBuffer + 200) );
    returnVal->mredSens13 = rawMredSens13*0.001;

    rawMredSens21 = *( (S16*) (rxBuffer + 202) );
    returnVal->mredSens21 = rawMredSens21*0.001;

    rawMredSens23 = *( (S16*) (rxBuffer + 204) );
    returnVal->mredSens23 = rawMredSens23*0.001;

    rawMredSens31 = *( (S16*) (rxBuffer + 206) );
    returnVal->mredSens31 = rawMredSens31*0.001;

    rawMredSens32 = *( (S16*) (rxBuffer + 208) );
    returnVal->mredSens32 = rawMredSens32*0.001;

    rawStarAngle1 = *( (S16*) (rxBuffer + 210) );
    returnVal->starAngle1 = rawStarAngle1*0.01;

    rawStarAngle2 = *( (S16*) (rxBuffer + 212) );
    returnVal->starAngle2 = rawStarAngle2*0.01;

    rawStarAngle3 = *( (S16*) (rxBuffer + 214) );
    returnVal->starAngle3 = rawStarAngle3*0.01;

    returnVal->starExposure = *( (U16*) (rxBuffer + 216) );

    returnVal->starGain = *( (U16*) (rxBuffer + 218) );

    returnVal->detectionThreshold = *( (U8*) (rxBuffer + 220) );

    returnVal->starThreshold = *( (U8*) (rxBuffer + 221) );

    returnVal->maxStarMatched = *( (U8*) (rxBuffer + 222) );

    returnVal->starTimeoutTime = *( (U16*) (rxBuffer + 223) );

    returnVal->maxStarPixel = *( (U8*) (rxBuffer + 225) );

    returnVal->minStarPixel = *( (U8*) (rxBuffer + 226) );

    rawStarErrorMargin = *( (U8*) (rxBuffer + 227) );
    returnVal->starErrorMargin = rawStarErrorMargin*0.01;

    returnVal->starDelayTime = *( (U16*) (rxBuffer + 228) );

    returnVal->starCentX = *((F32*)(rxBuffer + 230));

    returnVal->starCentY = *((F32*)(rxBuffer + 234));

    returnVal->starFocal = *((F32*)(rxBuffer + 238));

    returnVal->starLensK1 = *((F32*)(rxBuffer + 242));

    returnVal->starLensK2 = *((F32*)(rxBuffer + 246));

    returnVal->starLensP1 = *((F32*)(rxBuffer + 250));

    returnVal->starLensP2 = *((F32*)(rxBuffer + 254));

    returnVal->starWindowWidth = *( (U8*) (rxBuffer + 258) );

    rawStarTrackingMargin = *( (U8*) (rxBuffer + 259) );
    returnVal->starTrackingMargin = rawStarTrackingMargin/100.0;

    rawStarValidationMargin = *( (U8*) (rxBuffer + 260) );
    returnVal->starValidationMargin = rawStarValidationMargin/100.0;

    returnVal->starModuleEnable = (rxBuffer[261] & 0x01) >> 0;

    returnVal->starLocationPredictionEnable = (rxBuffer[261] & 0x02) >> 1;


    rawStarSearchWidth = *( (U8*) (rxBuffer + 262) );
    returnVal->starSearchWidth = rawStarSearchWidth/5.0;

    returnVal->ks = *((F32*)(rxBuffer + 263));

    returnVal->kd = *((F32*)(rxBuffer + 267));

    rawwy_ref = *( (S16*) (rxBuffer + 271) );
    returnVal->wy_ref = rawwy_ref*0.001;

    returnVal->kdf = *((F32*)(rxBuffer + 273));

    returnVal->kh = *((F32*)(rxBuffer + 277));

    returnVal->kn = *((F32*)(rxBuffer + 281));

    returnVal->kp1 = *((F32*)(rxBuffer + 285));

    returnVal->kd1 = *((F32*)(rxBuffer + 289));

    returnVal->h_ref = *((F32*)(rxBuffer + 293));

    returnVal->kp2 = *((F32*)(rxBuffer + 297));

    returnVal->kd2 = *((F32*)(rxBuffer + 301));

    returnVal->h_bias = *((F32*)(rxBuffer + 305));

    enumVal = (rxBuffer[309] >> 0) & 127;
    returnVal->sunPointFacet = (CUBEACP_AxisSelect_t) enumVal;

    returnVal->wheelErrorHandling = (rxBuffer[309] & 0x80) >> 7;

    returnVal->kp3 = *((F32*)(rxBuffer + 310));

    returnVal->kd3 = *((F32*)(rxBuffer + 314));

    returnVal->ki3 = *((F32*)(rxBuffer + 318));

    enumVal = rxBuffer[322];
    returnVal->targetTrackFacet = (CUBEACP_AxisSelect_t) enumVal;

    returnVal->ixx = *((F32*)(rxBuffer + 323));

    returnVal->iyy = *((F32*)(rxBuffer + 327));

    returnVal->izz = *((F32*)(rxBuffer + 331));

    returnVal->ixy = *((F32*)(rxBuffer + 335));

    returnVal->ixz = *((F32*)(rxBuffer + 339));

    returnVal->iyz = *((F32*)(rxBuffer + 343));

    returnVal->magRateNoise = *((F32*)(rxBuffer + 347));

    returnVal->ekfSysNoise = *((F32*)(rxBuffer + 351));

    returnVal->cssNoise = *((F32*)(rxBuffer + 355));

    returnVal->sunNoise = *((F32*)(rxBuffer + 359));

    returnVal->nadirNoise = *((F32*)(rxBuffer + 363));

    returnVal->magNoise = *((F32*)(rxBuffer + 367));

    returnVal->starNoise = *((F32*)(rxBuffer + 371));

    returnVal->useSunEst = (rxBuffer[375] & 0x01) >> 0;

    returnVal->useNadirEst = (rxBuffer[375] & 0x02) >> 1;

    returnVal->useCssEst = (rxBuffer[375] & 0x04) >> 2;

    returnVal->useStarEst = (rxBuffer[375] & 0x08) >> 3;

    returnVal->terminatorCheck = (rxBuffer[375] & 0x10) >> 4;

    returnVal->autoRecoverMtm = (rxBuffer[375] & 0x20) >> 5;

    enumVal = (rxBuffer[375] >> 6) & 3;
    returnVal->magMode = (CUBEACP_MagModeVal_t) enumVal;

    enumVal = (rxBuffer[376] >> 0) & 3;
    returnVal->magRawTlm2Selection = (CUBEACP_MagModeVal_t) enumVal;

    returnVal->rateSensorErrorHandling = (rxBuffer[376] & 0x04) >> 2;

    returnVal->wheelPowerOn30sDelay = (rxBuffer[376] & 0x08) >> 3;


    returnVal->cam1Cam2Period = *( (U8*) (rxBuffer + 377) );

    rawAInclCoeff = *( (U16*) (rxBuffer + 378) );
    returnVal->aInclCoeff = rawAInclCoeff*0.001;

    rawARaanCoeff = *( (U16*) (rxBuffer + 380) );
    returnVal->aRaanCoeff = rawARaanCoeff*0.001;

    rawAEccCoeff = *( (U16*) (rxBuffer + 382) );
    returnVal->aEccCoeff = rawAEccCoeff*0.001;

    rawAArgPerCoeff = *( (U16*) (rxBuffer + 384) );
    returnVal->aArgPerCoeff = rawAArgPerCoeff*0.001;

    rawATimeCoeff = *( (U16*) (rxBuffer + 386) );
    returnVal->aTimeCoeff = rawATimeCoeff*0.001;

    rawAPosCoeff = *( (U16*) (rxBuffer + 388) );
    returnVal->aPosCoeff = rawAPosCoeff*0.001;

    rawAsgp4MaxPosError = *( (U8*) (rxBuffer + 390) );
    returnVal->asgp4MaxPosError = rawAsgp4MaxPosError*0.1;

    enumVal = rxBuffer[391];
    returnVal->asgp4Filter = (CUBEACP_AsgpFilter_t) enumVal;

    rawAsgp4Xp = *( (S32*) (rxBuffer + 392) );
    returnVal->asgp4Xp = rawAsgp4Xp*0.0000001;

    rawAsgp4Yp = *( (S32*) (rxBuffer + 396) );
    returnVal->asgp4Yp = rawAsgp4Yp*0.0000001;

    returnVal->asgp4GpsRollover = *( (U8*) (rxBuffer + 400) );

    rawAsgp4PosSdTh = *( (U8*) (rxBuffer + 401) );
    returnVal->asgp4PosSdTh = rawAsgp4PosSdTh*0.1;

    rawAsgp4VelSdTh = *( (U8*) (rxBuffer + 402) );
    returnVal->asgp4VelSdTh = rawAsgp4VelSdTh*0.01;

    returnVal->asgp4MinSat = *( (U8*) (rxBuffer + 403) );

    rawAsgp4TimeGain = *( (U8*) (rxBuffer + 404) );
    returnVal->asgp4TimeGain = rawAsgp4TimeGain*0.01;

    rawAsgp4MaxLag = *( (U8*) (rxBuffer + 405) );
    returnVal->asgp4MaxLag = rawAsgp4MaxLag*0.01;

    returnVal->asgp4MinSamples = *( (U16*) (rxBuffer + 406) );

    memcpy(returnVal->userConSettings, rxBuffer + 408, 48);

    memcpy(returnVal->userEstSettings, rxBuffer + 456, 48);

    if ((returnVal->starCentX < -5000) || (returnVal->starCentX > 5000))
        return TlmRangeError;

    if ((returnVal->starCentY < -5000) || (returnVal->starCentY > 5000))
        return TlmRangeError;

    if ((returnVal->starFocal < 5) || (returnVal->starFocal > 7))
        return TlmRangeError;

    if ((returnVal->starLensK1 < -1) || (returnVal->starLensK1 > 1))
        return TlmRangeError;

    if ((returnVal->starLensK2 < -1) || (returnVal->starLensK2 > 1))
        return TlmRangeError;

    if ((returnVal->starLensP1 < -1) || (returnVal->starLensP1 > 1))
        return TlmRangeError;

    if ((returnVal->starLensP2 < -1) || (returnVal->starLensP2 > 1))
        return TlmRangeError;

    if ((returnVal->ks < 0) || (returnVal->ks > 10000))
        return TlmRangeError;

    if ((returnVal->kd < 0) || (returnVal->kd > 10000))
        return TlmRangeError;

    if ((returnVal->wy_ref < -32000) || (returnVal->wy_ref > 32000))
        return TlmRangeError;

    if ((returnVal->kdf < 0) || (returnVal->kdf > 100))
        return TlmRangeError;

    if ((returnVal->kh < 0) || (returnVal->kh > 10000))
        return TlmRangeError;

    if ((returnVal->kn < 0) || (returnVal->kn > 10000))
        return TlmRangeError;

    if ((returnVal->kp1 < 0) || (returnVal->kp1 > 100))
        return TlmRangeError;

    if ((returnVal->kd1 < 0) || (returnVal->kd1 > 100))
        return TlmRangeError;

    if ((returnVal->h_ref < -10) || (returnVal->h_ref > 0))
        return TlmRangeError;

    if ((returnVal->kp2 < 0) || (returnVal->kp2 > 100))
        return TlmRangeError;

    if ((returnVal->kd2 < 0) || (returnVal->kd2 > 100))
        return TlmRangeError;

    if ((returnVal->h_bias < -10) || (returnVal->h_bias > 10))
        return TlmRangeError;

    if ((returnVal->kp3 < 0) || (returnVal->kp3 > 100))
        return TlmRangeError;

    if ((returnVal->kd3 < 0) || (returnVal->kd3 > 100))
        return TlmRangeError;

    if ((returnVal->ki3 < 0) || (returnVal->ki3 > 100))
        return TlmRangeError;

    if ((returnVal->ixx < 0) || (returnVal->ixx > 10))
        return TlmRangeError;

    if ((returnVal->iyy < 0) || (returnVal->iyy > 10))
        return TlmRangeError;

    if ((returnVal->izz < 0) || (returnVal->izz > 10))
        return TlmRangeError;

    if ((returnVal->ixy < -10) || (returnVal->ixy > 10))
        return TlmRangeError;

    if ((returnVal->ixz < -10) || (returnVal->ixz > 10))
        return TlmRangeError;

    if ((returnVal->iyz < -10) || (returnVal->iyz > 10))
        return TlmRangeError;

    if ((returnVal->magRateNoise < 0) || (returnVal->magRateNoise > 100))
        return TlmRangeError;

    if ((returnVal->ekfSysNoise < 0) || (returnVal->ekfSysNoise > 100))
        return TlmRangeError;

    if ((returnVal->cssNoise < 0) || (returnVal->cssNoise > 100))
        return TlmRangeError;

    if ((returnVal->sunNoise < 0) || (returnVal->sunNoise > 100))
        return TlmRangeError;

    if ((returnVal->nadirNoise < 0) || (returnVal->nadirNoise > 100))
        return TlmRangeError;

    if ((returnVal->magNoise < 0) || (returnVal->magNoise > 100))
        return TlmRangeError;

    if ((returnVal->starNoise < 0) || (returnVal->starNoise > 100))
        return TlmRangeError;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsExecTimesTlm(uint8_t* rxBuffer, CUBEACP_AdcsExecTimes_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->timeAdcsUpdate = *( (U16*) (rxBuffer + 0) );

    returnVal->timeSensorActuatorComms = *( (U16*) (rxBuffer + 2) );

    returnVal->timeSgp4 = *( (U16*) (rxBuffer + 4) );

    returnVal->timeIgrf = *( (U16*) (rxBuffer + 6) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsMeasureTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawMagX;
    S16 rawMagY;
    S16 rawMagZ;
    S16 rawCssX;
    S16 rawCssY;
    S16 rawCssZ;
    S16 rawSunX;
    S16 rawSunY;
    S16 rawSunZ;
    S16 rawNadirX;
    S16 rawNadirY;
    S16 rawNadirZ;
    S16 rawRateX;
    S16 rawRateY;
    S16 rawRateZ;
    S16 rawStar1BX;
    S16 rawStar1BY;
    S16 rawStar1BZ;
    S16 rawStar1OX;
    S16 rawStar1OY;
    S16 rawStar1OZ;
    S16 rawStar2BX;
    S16 rawStar2BY;
    S16 rawStar2BZ;
    S16 rawStar2OX;
    S16 rawStar2OY;
    S16 rawStar2OZ;
    S16 rawStar3BX;
    S16 rawStar3BY;
    S16 rawStar3BZ;
    S16 rawStar3OX;
    S16 rawStar3OY;
    S16 rawStar3OZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawMagX = *( (S16*) (rxBuffer + 0) );
    returnVal->magX = rawMagX*0.01;

    rawMagY = *( (S16*) (rxBuffer + 2) );
    returnVal->magY = rawMagY*0.01;

    rawMagZ = *( (S16*) (rxBuffer + 4) );
    returnVal->magZ = rawMagZ*0.01;

    rawCssX = *( (S16*) (rxBuffer + 6) );
    returnVal->cssX = rawCssX/10000.0;

    rawCssY = *( (S16*) (rxBuffer + 8) );
    returnVal->cssY = rawCssY/10000.0;

    rawCssZ = *( (S16*) (rxBuffer + 10) );
    returnVal->cssZ = rawCssZ/10000.0;

    rawSunX = *( (S16*) (rxBuffer + 12) );
    returnVal->sunX = rawSunX/10000.0;

    rawSunY = *( (S16*) (rxBuffer + 14) );
    returnVal->sunY = rawSunY/10000.0;

    rawSunZ = *( (S16*) (rxBuffer + 16) );
    returnVal->sunZ = rawSunZ/10000.0;

    rawNadirX = *( (S16*) (rxBuffer + 18) );
    returnVal->nadirX = rawNadirX/10000.0;

    rawNadirY = *( (S16*) (rxBuffer + 20) );
    returnVal->nadirY = rawNadirY/10000.0;

    rawNadirZ = *( (S16*) (rxBuffer + 22) );
    returnVal->nadirZ = rawNadirZ/10000.0;

    rawRateX = *( (S16*) (rxBuffer + 24) );
    returnVal->rateX = rawRateX*0.01;

    rawRateY = *( (S16*) (rxBuffer + 26) );
    returnVal->rateY = rawRateY*0.01;

    rawRateZ = *( (S16*) (rxBuffer + 28) );
    returnVal->rateZ = rawRateZ*0.01;

    returnVal->speedX = *( (S16*) (rxBuffer + 30) );

    returnVal->speedY = *( (S16*) (rxBuffer + 32) );

    returnVal->speedZ = *( (S16*) (rxBuffer + 34) );

    rawStar1BX = *( (S16*) (rxBuffer + 36) );
    returnVal->star1BX = rawStar1BX/10000.0;

    rawStar1BY = *( (S16*) (rxBuffer + 38) );
    returnVal->star1BY = rawStar1BY/10000.0;

    rawStar1BZ = *( (S16*) (rxBuffer + 40) );
    returnVal->star1BZ = rawStar1BZ/10000.0;

    rawStar1OX = *( (S16*) (rxBuffer + 42) );
    returnVal->star1OX = rawStar1OX/10000.0;

    rawStar1OY = *( (S16*) (rxBuffer + 44) );
    returnVal->star1OY = rawStar1OY/10000.0;

    rawStar1OZ = *( (S16*) (rxBuffer + 46) );
    returnVal->star1OZ = rawStar1OZ/10000.0;

    rawStar2BX = *( (S16*) (rxBuffer + 48) );
    returnVal->star2BX = rawStar2BX/10000.0;

    rawStar2BY = *( (S16*) (rxBuffer + 50) );
    returnVal->star2BY = rawStar2BY/10000.0;

    rawStar2BZ = *( (S16*) (rxBuffer + 52) );
    returnVal->star2BZ = rawStar2BZ/10000.0;

    rawStar2OX = *( (S16*) (rxBuffer + 54) );
    returnVal->star2OX = rawStar2OX/10000.0;

    rawStar2OY = *( (S16*) (rxBuffer + 56) );
    returnVal->star2OY = rawStar2OY/10000.0;

    rawStar2OZ = *( (S16*) (rxBuffer + 58) );
    returnVal->star2OZ = rawStar2OZ/10000.0;

    rawStar3BX = *( (S16*) (rxBuffer + 60) );
    returnVal->star3BX = rawStar3BX/10000.0;

    rawStar3BY = *( (S16*) (rxBuffer + 62) );
    returnVal->star3BY = rawStar3BY/10000.0;

    rawStar3BZ = *( (S16*) (rxBuffer + 64) );
    returnVal->star3BZ = rawStar3BZ/10000.0;

    rawStar3OX = *( (S16*) (rxBuffer + 66) );
    returnVal->star3OX = rawStar3OX/10000.0;

    rawStar3OY = *( (S16*) (rxBuffer + 68) );
    returnVal->star3OY = rawStar3OY/10000.0;

    rawStar3OZ = *( (S16*) (rxBuffer + 70) );
    returnVal->star3OZ = rawStar3OZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsMiscCurrentsTlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    U16 rawCubeStarCurrent;
    U16 rawMagtorqCurrent;
    S16 rawCubeStarTemp;
    if (returnVal == 0)
        return PointerIsNull;

    rawCubeStarCurrent = *( (U16*) (rxBuffer + 0) );
    returnVal->cubeStarCurrent = rawCubeStarCurrent*0.01;

    rawMagtorqCurrent = *( (U16*) (rxBuffer + 2) );
    returnVal->magtorqCurrent = rawMagtorqCurrent*0.1;

    rawCubeStarTemp = *( (S16*) (rxBuffer + 4) );
    returnVal->cubeStarTemp = rawCubeStarTemp/100.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsPowerTlm(uint8_t* rxBuffer, CUBEACP_AdcsPower_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = (rxBuffer[0] >> 0) & 3;
    returnVal->cubeControlSignalPower = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[0] >> 2) & 3;
    returnVal->cubeControlMotorPower = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[0] >> 4) & 3;
    returnVal->cubeSense1Power = (CUBEACP_PowerSelectCubeSense_t) enumVal;

    enumVal = (rxBuffer[0] >> 6) & 3;
    returnVal->cubeSense2Power = (CUBEACP_PowerSelectCubeSense_t) enumVal;

    enumVal = (rxBuffer[1] >> 0) & 3;
    returnVal->cubeStarPower = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[1] >> 2) & 3;
    returnVal->cubeWheel1Power = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[1] >> 4) & 3;
    returnVal->cubeWheel2Power = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[1] >> 6) & 3;
    returnVal->cubeWheel3Power = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[2] >> 0) & 3;
    returnVal->motorPower = (CUBEACP_PowerSelect_t) enumVal;

    enumVal = (rxBuffer[2] >> 2) & 3;
    returnVal->gpsLnaPower = (CUBEACP_PowerSelect_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsPowerMeasureTlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    U16 rawCubeSense1_3V3Current;
    U16 rawCubeSense1_CamCurrent;
    U16 rawCubeSense2_3V3Current;
    U16 rawCubeSense2_CamCurrent;
    U16 rawCubeControl3V3Current;
    U16 rawCubeControl5VCurrent;
    U16 rawCubeControlBatCurrent;
    U16 rawWheel1Current;
    U16 rawWheel2Current;
    U16 rawWheel3Current;
    U16 rawCubeStarCurrent;
    U16 rawMagtorqCurrent;
    S16 rawCubeStarTemp;
    S16 rawMagnetometerTemp;
    S16 rawRedundentMagnetometerTemp;
    if (returnVal == 0)
        return PointerIsNull;

    rawCubeSense1_3V3Current = *( (U16*) (rxBuffer + 0) );
    returnVal->cubeSense1_3V3Current = rawCubeSense1_3V3Current*0.1;

    rawCubeSense1_CamCurrent = *( (U16*) (rxBuffer + 2) );
    returnVal->cubeSense1_CamCurrent = rawCubeSense1_CamCurrent*0.1;

    rawCubeSense2_3V3Current = *( (U16*) (rxBuffer + 4) );
    returnVal->cubeSense2_3V3Current = rawCubeSense2_3V3Current*0.1;

    rawCubeSense2_CamCurrent = *( (U16*) (rxBuffer + 6) );
    returnVal->cubeSense2_CamCurrent = rawCubeSense2_CamCurrent*0.1;

    rawCubeControl3V3Current = *( (U16*) (rxBuffer + 8) );
    returnVal->cubeControl3V3Current = rawCubeControl3V3Current*0.48828125;

    rawCubeControl5VCurrent = *( (U16*) (rxBuffer + 10) );
    returnVal->cubeControl5VCurrent = rawCubeControl5VCurrent*0.48828125;

    rawCubeControlBatCurrent = *( (U16*) (rxBuffer + 12) );
    returnVal->cubeControlBatCurrent = rawCubeControlBatCurrent*0.48828125;

    rawWheel1Current = *( (U16*) (rxBuffer + 14) );
    returnVal->wheel1Current = rawWheel1Current*0.01;

    rawWheel2Current = *( (U16*) (rxBuffer + 16) );
    returnVal->wheel2Current = rawWheel2Current*0.01;

    rawWheel3Current = *( (U16*) (rxBuffer + 18) );
    returnVal->wheel3Current = rawWheel3Current*0.01;

    rawCubeStarCurrent = *( (U16*) (rxBuffer + 20) );
    returnVal->cubeStarCurrent = rawCubeStarCurrent*0.01;

    rawMagtorqCurrent = *( (U16*) (rxBuffer + 22) );
    returnVal->magtorqCurrent = rawMagtorqCurrent*0.1;

    rawCubeStarTemp = *( (S16*) (rxBuffer + 24) );
    returnVal->cubeStarTemp = rawCubeStarTemp/100.0;

    returnVal->mCUTemp = *( (S16*) (rxBuffer + 26) );

    rawMagnetometerTemp = *( (S16*) (rxBuffer + 28) );
    returnVal->magnetometerTemp = rawMagnetometerTemp/10.0;

    rawRedundentMagnetometerTemp = *( (S16*) (rxBuffer + 30) );
    returnVal->redundentMagnetometerTemp = rawRedundentMagnetometerTemp/10.0;

    returnVal->xRateTemp = *( (S16*) (rxBuffer + 32) );

    returnVal->yRateTemp = *( (S16*) (rxBuffer + 34) );

    returnVal->zRateTemp = *( (S16*) (rxBuffer + 36) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsStateTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    S16 rawRoll;
    S16 rawPitch;
    S16 rawYaw;
    S16 rawRateX;
    S16 rawRateY;
    S16 rawRateZ;
    S16 rawPositionX;
    S16 rawPositionY;
    S16 rawPositionZ;
    S16 rawVelocityX;
    S16 rawVelocityY;
    S16 rawVelocityZ;
    S16 rawLatitude;
    S16 rawLongitude;
    U16 rawAltitude;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = (rxBuffer[0] >> 0) & 15;
    returnVal->estimMode = (CUBEACP_EstimModeSelect_t) enumVal;

    enumVal = (rxBuffer[0] >> 4) & 15;
    returnVal->controlMode = (CUBEACP_ConModeSelect_t) enumVal;

    enumVal = (rxBuffer[1] >> 0) & 3;
    returnVal->adcsRunMode = (CUBEACP_AdcsRunMode_t) enumVal;

    enumVal = (rxBuffer[1] >> 2) & 3;
    returnVal->asgp4Mode = (CUBEACP_Asgp4ModeSelect_t) enumVal;

    returnVal->cubeControlSignalPower = (rxBuffer[1] & 0x10) >> 4;

    returnVal->cubeControlMotorPower = (rxBuffer[1] & 0x20) >> 5;

    returnVal->cubeSense1Power = (rxBuffer[1] & 0x40) >> 6;

    returnVal->cubeSense2Power = (rxBuffer[1] & 0x80) >> 7;

    returnVal->cubeWheel1Power = (rxBuffer[2] & 0x01) >> 0;

    returnVal->cubeWheel2Power = (rxBuffer[2] & 0x02) >> 1;

    returnVal->cubeWheel3Power = (rxBuffer[2] & 0x04) >> 2;

    returnVal->cubeStarPower = (rxBuffer[2] & 0x08) >> 3;

    returnVal->gpsReceiverPower = (rxBuffer[2] & 0x10) >> 4;

    returnVal->gpsLnaPower = (rxBuffer[2] & 0x20) >> 5;

    returnVal->motorDriverPower = (rxBuffer[2] & 0x40) >> 6;

    returnVal->sunAboveHorizon = (rxBuffer[2] & 0x80) >> 7;

    returnVal->cubeSense1CommsError = (rxBuffer[3] & 0x01) >> 0;

    returnVal->cubeSense2CommsError = (rxBuffer[3] & 0x02) >> 1;

    returnVal->cubeControlSignalCommsError = (rxBuffer[3] & 0x04) >> 2;

    returnVal->cubeControlMotorCommsError = (rxBuffer[3] & 0x08) >> 3;

    returnVal->cubeWheel1CommsError = (rxBuffer[3] & 0x10) >> 4;

    returnVal->cubeWheel2CommsError = (rxBuffer[3] & 0x20) >> 5;

    returnVal->cubeWheel3CommsError = (rxBuffer[3] & 0x40) >> 6;

    returnVal->cubeStarCommsError = (rxBuffer[3] & 0x80) >> 7;

    returnVal->magRangeError = (rxBuffer[4] & 0x01) >> 0;

    returnVal->cam1OvercurrentSram = (rxBuffer[4] & 0x02) >> 1;

    returnVal->cam1Overcurrent3V3 = (rxBuffer[4] & 0x04) >> 2;

    returnVal->cam1SensNotIdle = (rxBuffer[4] & 0x08) >> 3;

    returnVal->cam1SensDetectError = (rxBuffer[4] & 0x10) >> 4;

    returnVal->sunSensRangeError = (rxBuffer[4] & 0x20) >> 5;

    returnVal->cam2OvercurrentSram = (rxBuffer[4] & 0x40) >> 6;

    returnVal->cam2Overcurrent3V3 = (rxBuffer[4] & 0x80) >> 7;

    returnVal->cam2SensNotIdle = (rxBuffer[5] & 0x01) >> 0;

    returnVal->cam2SensDetectError = (rxBuffer[5] & 0x02) >> 1;

    returnVal->nadirSensRangeError = (rxBuffer[5] & 0x04) >> 2;

    returnVal->rateSensRangeError = (rxBuffer[5] & 0x08) >> 3;

    returnVal->wheelSpeedRangeError = (rxBuffer[5] & 0x10) >> 4;

    returnVal->cssError = (rxBuffer[5] & 0x20) >> 5;

    returnVal->starMatchError = (rxBuffer[5] & 0x40) >> 6;

    returnVal->starTrackOvercurrent = (rxBuffer[5] & 0x80) >> 7;

    returnVal->orbitParamsInvalidError = (rxBuffer[6] & 0x01) >> 0;

    returnVal->configInvalidError = (rxBuffer[6] & 0x02) >> 1;

    returnVal->controlModeNotAllowed = (rxBuffer[6] & 0x04) >> 2;

    returnVal->estimatorNotAllowed = (rxBuffer[6] & 0x08) >> 3;

    enumVal = (rxBuffer[6] >> 4) & 3;
    returnVal->curMagMode = (CUBEACP_MagModeVal_t) enumVal;

    returnVal->magfieldModelError = (rxBuffer[6] & 0x40) >> 6;

    returnVal->nodeRecoveryError = (rxBuffer[6] & 0x80) >> 7;

    returnVal->cubeSense1RuntimeError = (rxBuffer[7] & 0x01) >> 0;

    returnVal->cubeSense2RuntimeError = (rxBuffer[7] & 0x02) >> 1;

    returnVal->cubeControlSignalRuntimeError = (rxBuffer[7] & 0x04) >> 2;

    returnVal->cubeControlMotorRuntimeError = (rxBuffer[7] & 0x08) >> 3;

    returnVal->cubeWheel1RuntimeError = (rxBuffer[7] & 0x10) >> 4;

    returnVal->cubeWheel2RuntimeError = (rxBuffer[7] & 0x20) >> 5;

    returnVal->cubeWheel3RuntimeError = (rxBuffer[7] & 0x40) >> 6;

    returnVal->cubeStarRuntimeError = (rxBuffer[7] & 0x80) >> 7;

    returnVal->magnetometerError = (rxBuffer[8] & 0x01) >> 0;

    returnVal->rateSensorFailure = (rxBuffer[8] & 0x02) >> 1;


    rawRoll = *( (S16*) (rxBuffer + 12) );
    returnVal->roll = rawRoll*0.01;

    rawPitch = *( (S16*) (rxBuffer + 14) );
    returnVal->pitch = rawPitch*0.01;

    rawYaw = *( (S16*) (rxBuffer + 16) );
    returnVal->yaw = rawYaw*0.01;

    returnVal->q1 = *( (S16*) (rxBuffer + 18) );

    returnVal->q2 = *( (S16*) (rxBuffer + 20) );

    returnVal->q3 = *( (S16*) (rxBuffer + 22) );

    rawRateX = *( (S16*) (rxBuffer + 24) );
    returnVal->rateX = rawRateX*0.01;

    rawRateY = *( (S16*) (rxBuffer + 26) );
    returnVal->rateY = rawRateY*0.01;

    rawRateZ = *( (S16*) (rxBuffer + 28) );
    returnVal->rateZ = rawRateZ*0.01;

    rawPositionX = *( (S16*) (rxBuffer + 30) );
    returnVal->positionX = rawPositionX*0.25;

    rawPositionY = *( (S16*) (rxBuffer + 32) );
    returnVal->positionY = rawPositionY*0.25;

    rawPositionZ = *( (S16*) (rxBuffer + 34) );
    returnVal->positionZ = rawPositionZ*0.25;

    rawVelocityX = *( (S16*) (rxBuffer + 36) );
    returnVal->velocityX = rawVelocityX*0.25;

    rawVelocityY = *( (S16*) (rxBuffer + 38) );
    returnVal->velocityY = rawVelocityY*0.25;

    rawVelocityZ = *( (S16*) (rxBuffer + 40) );
    returnVal->velocityZ = rawVelocityZ*0.25;

    rawLatitude = *( (S16*) (rxBuffer + 42) );
    returnVal->latitude = rawLatitude*0.01;

    rawLongitude = *( (S16*) (rxBuffer + 44) );
    returnVal->longitude = rawLongitude*0.01;

    rawAltitude = *( (U16*) (rxBuffer + 46) );
    returnVal->altitude = rawAltitude*0.01;

    returnVal->posEcefX = *( (S16*) (rxBuffer + 48) );

    returnVal->posEcefY = *( (S16*) (rxBuffer + 50) );

    returnVal->posEcefZ = *( (S16*) (rxBuffer + 52) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsSystemConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsSystemConfig_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = (rxBuffer[0] >> 0) & 15;
    returnVal->acpType = (CUBEACP_AcpProgramType_t) enumVal;

    enumVal = (rxBuffer[0] >> 4) & 15;
    returnVal->specialControl = (CUBEACP_SpecialConSelect_t) enumVal;

    returnVal->ccSignalVer = *( (U8*) (rxBuffer + 1) );

    returnVal->ccMotorVer = *( (U8*) (rxBuffer + 2) );

    returnVal->cs1Ver = *( (U8*) (rxBuffer + 3) );

    returnVal->cs2Ver = *( (U8*) (rxBuffer + 4) );

    enumVal = (rxBuffer[5] >> 0) & 15;
    returnVal->csCam1Type = (CUBEACP_CsCamType_t) enumVal;

    enumVal = (rxBuffer[5] >> 4) & 15;
    returnVal->csCam2Type = (CUBEACP_CsCamType_t) enumVal;

    returnVal->cubeStarVer = *( (U8*) (rxBuffer + 6) );

    enumVal = (rxBuffer[7] >> 0) & 15;
    returnVal->gpsType = (CUBEACP_GpsSelect_t) enumVal;

    returnVal->hasRedMag = (rxBuffer[7] & 0x10) >> 4;


    returnVal->mqx = *((F32*)(rxBuffer + 8));

    returnVal->mqy = *((F32*)(rxBuffer + 12));

    returnVal->mqz = *((F32*)(rxBuffer + 16));

    returnVal->mtTmin = *((F32*)(rxBuffer + 20));

    returnVal->mtTmax = *((F32*)(rxBuffer + 24));

    returnVal->nSatX = *((F32*)(rxBuffer + 28));

    returnVal->nSatY = *((F32*)(rxBuffer + 32));

    returnVal->nSatZ = *((F32*)(rxBuffer + 36));

    returnVal->hSatX = *((F32*)(rxBuffer + 40));

    returnVal->hSatY = *((F32*)(rxBuffer + 44));

    returnVal->hSatZ = *((F32*)(rxBuffer + 48));

    returnVal->iwx = *((F32*)(rxBuffer + 52));

    returnVal->iwy = *((F32*)(rxBuffer + 56));

    returnVal->iwz = *((F32*)(rxBuffer + 60));

    returnVal->ndel = *((F32*)(rxBuffer + 64));

    returnVal->biasX_d1 = *((F32*)(rxBuffer + 68));

    returnVal->biasY_d1 = *((F32*)(rxBuffer + 72));

    returnVal->biasZ_d1 = *((F32*)(rxBuffer + 76));

    returnVal->biasX_d2 = *((F32*)(rxBuffer + 80));

    returnVal->biasY_d2 = *((F32*)(rxBuffer + 84));

    returnVal->biasZ_d2 = *((F32*)(rxBuffer + 88));

    returnVal->sensX_s1 = *((F32*)(rxBuffer + 92));

    returnVal->sensY_s1 = *((F32*)(rxBuffer + 96));

    returnVal->sensZ_s1 = *((F32*)(rxBuffer + 100));

    returnVal->sensX_s2 = *((F32*)(rxBuffer + 104));

    returnVal->sensY_s2 = *((F32*)(rxBuffer + 108));

    returnVal->sensZ_s2 = *((F32*)(rxBuffer + 112));

    returnVal->red_BiasX_d1 = *((F32*)(rxBuffer + 116));

    returnVal->red_BiasY_d1 = *((F32*)(rxBuffer + 120));

    returnVal->red_BiasZ_d1 = *((F32*)(rxBuffer + 124));

    returnVal->red_BiasX_d2 = *((F32*)(rxBuffer + 128));

    returnVal->red_BiasY_d2 = *((F32*)(rxBuffer + 132));

    returnVal->red_BiasZ_d2 = *((F32*)(rxBuffer + 136));

    returnVal->red_SensX_s1 = *((F32*)(rxBuffer + 140));

    returnVal->red_SensY_s1 = *((F32*)(rxBuffer + 144));

    returnVal->red_SensZ_s1 = *((F32*)(rxBuffer + 148));

    returnVal->red_SensX_s2 = *((F32*)(rxBuffer + 152));

    returnVal->red_SensY_s2 = *((F32*)(rxBuffer + 156));

    returnVal->red_SensZ_s2 = *((F32*)(rxBuffer + 160));

    enumVal = (rxBuffer[164] >> 0) & 15;
    returnVal->ccsEnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[164] >> 4) & 15;
    returnVal->ccsEnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[165] >> 0) & 15;
    returnVal->ccmEnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[165] >> 4) & 15;
    returnVal->ccmEnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[166] >> 0) & 15;
    returnVal->cccEnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[166] >> 4) & 15;
    returnVal->cccEnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[167] >> 0) & 15;
    returnVal->cSense1EnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[167] >> 4) & 15;
    returnVal->cSense1EnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[168] >> 0) & 15;
    returnVal->cSense2EnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[168] >> 4) & 15;
    returnVal->cSense2EnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[169] >> 0) & 15;
    returnVal->cStarEnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[169] >> 4) & 15;
    returnVal->cStarEnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[170] >> 0) & 15;
    returnVal->cW1EnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[170] >> 4) & 15;
    returnVal->cW1EnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[171] >> 0) & 15;
    returnVal->cW2EnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[171] >> 4) & 15;
    returnVal->cW2EnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    enumVal = (rxBuffer[172] >> 0) & 15;
    returnVal->cW3EnablePort = (CUBEACP_GpioPort_t) enumVal;

    enumVal = (rxBuffer[172] >> 4) & 15;
    returnVal->cW3EnablePin = (CUBEACP_GpioPortPin_t) enumVal;

    if ((returnVal->mqx < 0) || (returnVal->mqx > 2))
        return TlmRangeError;

    if ((returnVal->mqy < 0) || (returnVal->mqy > 2))
        return TlmRangeError;

    if ((returnVal->mqz < 0) || (returnVal->mqz > 2))
        return TlmRangeError;

    if ((returnVal->mtTmin < 0) || (returnVal->mtTmin > 1))
        return TlmRangeError;

    if ((returnVal->mtTmax < 0) || (returnVal->mtTmax > 1))
        return TlmRangeError;

    if ((returnVal->nSatX < 0) || (returnVal->nSatX > 0.1))
        return TlmRangeError;

    if ((returnVal->nSatY < 0) || (returnVal->nSatY > 0.1))
        return TlmRangeError;

    if ((returnVal->nSatZ < 0) || (returnVal->nSatZ > 0.1))
        return TlmRangeError;

    if ((returnVal->hSatX < 0) || (returnVal->hSatX > 0.1))
        return TlmRangeError;

    if ((returnVal->hSatY < 0) || (returnVal->hSatY > 0.1))
        return TlmRangeError;

    if ((returnVal->hSatZ < 0) || (returnVal->hSatZ > 0.1))
        return TlmRangeError;

    if ((returnVal->iwx < 0) || (returnVal->iwx > 0.001))
        return TlmRangeError;

    if ((returnVal->iwy < 0) || (returnVal->iwy > 0.001))
        return TlmRangeError;

    if ((returnVal->iwz < 0) || (returnVal->iwz > 0.001))
        return TlmRangeError;

    if ((returnVal->ndel < 0) || (returnVal->ndel > 0.1))
        return TlmRangeError;

    if ((returnVal->biasX_d1 < -10) || (returnVal->biasX_d1 > 10))
        return TlmRangeError;

    if ((returnVal->biasY_d1 < -10) || (returnVal->biasY_d1 > 10))
        return TlmRangeError;

    if ((returnVal->biasZ_d1 < -10) || (returnVal->biasZ_d1 > 10))
        return TlmRangeError;

    if ((returnVal->biasX_d2 < -10000) || (returnVal->biasX_d2 > 10000))
        return TlmRangeError;

    if ((returnVal->biasY_d2 < -10000) || (returnVal->biasY_d2 > 10000))
        return TlmRangeError;

    if ((returnVal->biasZ_d2 < -10000) || (returnVal->biasZ_d2 > 10000))
        return TlmRangeError;

    if ((returnVal->sensX_s1 < -1) || (returnVal->sensX_s1 > 1))
        return TlmRangeError;

    if ((returnVal->sensY_s1 < -1) || (returnVal->sensY_s1 > 1))
        return TlmRangeError;

    if ((returnVal->sensZ_s1 < -1) || (returnVal->sensZ_s1 > 1))
        return TlmRangeError;

    if ((returnVal->sensX_s2 < -10) || (returnVal->sensX_s2 > 10))
        return TlmRangeError;

    if ((returnVal->sensY_s2 < -10) || (returnVal->sensY_s2 > 10))
        return TlmRangeError;

    if ((returnVal->sensZ_s2 < -10) || (returnVal->sensZ_s2 > 10))
        return TlmRangeError;

    if ((returnVal->red_BiasX_d1 < -10) || (returnVal->red_BiasX_d1 > 10))
        return TlmRangeError;

    if ((returnVal->red_BiasY_d1 < -10) || (returnVal->red_BiasY_d1 > 10))
        return TlmRangeError;

    if ((returnVal->red_BiasZ_d1 < -10) || (returnVal->red_BiasZ_d1 > 10))
        return TlmRangeError;

    if ((returnVal->red_BiasX_d2 < -10000) || (returnVal->red_BiasX_d2 > 10000))
        return TlmRangeError;

    if ((returnVal->red_BiasY_d2 < -10000) || (returnVal->red_BiasY_d2 > 10000))
        return TlmRangeError;

    if ((returnVal->red_BiasZ_d2 < -10000) || (returnVal->red_BiasZ_d2 > 10000))
        return TlmRangeError;

    if ((returnVal->red_SensX_s1 < -1) || (returnVal->red_SensX_s1 > 1))
        return TlmRangeError;

    if ((returnVal->red_SensY_s1 < -1) || (returnVal->red_SensY_s1 > 1))
        return TlmRangeError;

    if ((returnVal->red_SensZ_s1 < -1) || (returnVal->red_SensZ_s1 > 1))
        return TlmRangeError;

    if ((returnVal->red_SensX_s2 < -10) || (returnVal->red_SensX_s2 > 10))
        return TlmRangeError;

    if ((returnVal->red_SensY_s2 < -10) || (returnVal->red_SensY_s2 > 10))
        return TlmRangeError;

    if ((returnVal->red_SensZ_s2 < -10) || (returnVal->red_SensZ_s2 > 10))
        return TlmRangeError;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsTemperatures1Tlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    S16 rawMagnetometerTemp;
    S16 rawRedundentMagnetometerTemp;
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->mCUTemp = *( (S16*) (rxBuffer + 0) );

    rawMagnetometerTemp = *( (S16*) (rxBuffer + 2) );
    returnVal->magnetometerTemp = rawMagnetometerTemp/10.0;

    rawRedundentMagnetometerTemp = *( (S16*) (rxBuffer + 4) );
    returnVal->redundentMagnetometerTemp = rawRedundentMagnetometerTemp/10.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAdcsTemperatures2Tlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->xRateTemp = *( (S16*) (rxBuffer + 0) );

    returnVal->yRateTemp = *( (S16*) (rxBuffer + 2) );

    returnVal->zRateTemp = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractAsgp4KepTleTlm(uint8_t* rxBuffer, CUBEACP_Asgp4KepTle_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->asgp4Complete = (rxBuffer[0] & 0x01) >> 0;

    enumVal = (rxBuffer[0] >> 1) & 127;
    returnVal->asgpErr = (CUBEACP_Asgp4Error_t) enumVal;

    returnVal->asgp4Epoch = *((F32*)(rxBuffer + 1));

    returnVal->asgp4Incli = *((F32*)(rxBuffer + 5));

    returnVal->asgp4Raan = *((F32*)(rxBuffer + 9));

    returnVal->asgp4Ecc = *((F32*)(rxBuffer + 13));

    returnVal->asgp4Aop = *((F32*)(rxBuffer + 17));

    returnVal->asgp4Ma = *((F32*)(rxBuffer + 21));

    returnVal->asgp4Mm = *((F32*)(rxBuffer + 25));

    returnVal->asgp4Bstar = *((F32*)(rxBuffer + 29));

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractASgp4ParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    U16 rawAInclCoeff;
    U16 rawARaanCoeff;
    U16 rawAEccCoeff;
    U16 rawAArgPerCoeff;
    U16 rawATimeCoeff;
    U16 rawAPosCoeff;
    U8 rawAsgp4MaxPosError;
    S32 rawAsgp4Xp;
    S32 rawAsgp4Yp;
    U8 rawAsgp4PosSdTh;
    U8 rawAsgp4VelSdTh;
    U8 rawAsgp4TimeGain;
    U8 rawAsgp4MaxLag;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    rawAInclCoeff = *( (U16*) (rxBuffer + 0) );
    returnVal->aInclCoeff = rawAInclCoeff*0.001;

    rawARaanCoeff = *( (U16*) (rxBuffer + 2) );
    returnVal->aRaanCoeff = rawARaanCoeff*0.001;

    rawAEccCoeff = *( (U16*) (rxBuffer + 4) );
    returnVal->aEccCoeff = rawAEccCoeff*0.001;

    rawAArgPerCoeff = *( (U16*) (rxBuffer + 6) );
    returnVal->aArgPerCoeff = rawAArgPerCoeff*0.001;

    rawATimeCoeff = *( (U16*) (rxBuffer + 8) );
    returnVal->aTimeCoeff = rawATimeCoeff*0.001;

    rawAPosCoeff = *( (U16*) (rxBuffer + 10) );
    returnVal->aPosCoeff = rawAPosCoeff*0.001;

    rawAsgp4MaxPosError = *( (U8*) (rxBuffer + 12) );
    returnVal->asgp4MaxPosError = rawAsgp4MaxPosError*0.1;

    enumVal = rxBuffer[13];
    returnVal->asgp4Filter = (CUBEACP_AsgpFilter_t) enumVal;

    rawAsgp4Xp = *( (S32*) (rxBuffer + 14) );
    returnVal->asgp4Xp = rawAsgp4Xp*0.0000001;

    rawAsgp4Yp = *( (S32*) (rxBuffer + 18) );
    returnVal->asgp4Yp = rawAsgp4Yp*0.0000001;

    returnVal->asgp4GpsRollover = *( (U8*) (rxBuffer + 22) );

    rawAsgp4PosSdTh = *( (U8*) (rxBuffer + 23) );
    returnVal->asgp4PosSdTh = rawAsgp4PosSdTh*0.1;

    rawAsgp4VelSdTh = *( (U8*) (rxBuffer + 24) );
    returnVal->asgp4VelSdTh = rawAsgp4VelSdTh*0.01;

    returnVal->asgp4MinSat = *( (U8*) (rxBuffer + 25) );

    rawAsgp4TimeGain = *( (U8*) (rxBuffer + 26) );
    returnVal->asgp4TimeGain = rawAsgp4TimeGain*0.01;

    rawAsgp4MaxLag = *( (U8*) (rxBuffer + 27) );
    returnVal->asgp4MaxLag = rawAsgp4MaxLag*0.01;

    returnVal->asgp4MinSamples = *( (U16*) (rxBuffer + 28) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCmdAttitudeTlm(uint8_t* rxBuffer, CUBEACP_CmdAttitude_t* returnVal)
{
    S16 rawRoll;
    S16 rawPitch;
    S16 rawYaw;
    if (returnVal == 0)
        return PointerIsNull;

    rawRoll = *( (S16*) (rxBuffer + 0) );
    returnVal->roll = rawRoll*0.01;

    rawPitch = *( (S16*) (rxBuffer + 2) );
    returnVal->pitch = rawPitch*0.01;

    rawYaw = *( (S16*) (rxBuffer + 4) );
    returnVal->yaw = rawYaw*0.01;

    if ((returnVal->roll < -9000) || (returnVal->roll > 9000))
        return TlmRangeError;

    if ((returnVal->pitch < -18000) || (returnVal->pitch > 18000))
        return TlmRangeError;

    if ((returnVal->yaw < -18000) || (returnVal->yaw > 18000))
        return TlmRangeError;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCmdTrackingTargetTlm(uint8_t* rxBuffer, CUBEACP_CmdTrackingTarget_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->longRef = *((F32*)(rxBuffer + 0));

    returnVal->latRef = *((F32*)(rxBuffer + 4));

    returnVal->altRef = *((F32*)(rxBuffer + 8));

    if ((returnVal->longRef < 0) || (returnVal->longRef > 360))
        return TlmRangeError;

    if ((returnVal->latRef < -90) || (returnVal->latRef > 90))
        return TlmRangeError;

    if ((returnVal->altRef < -20000) || (returnVal->altRef > 40000000))
        return TlmRangeError;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCoarseSunVecTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawCssX;
    S16 rawCssY;
    S16 rawCssZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawCssX = *( (S16*) (rxBuffer + 0) );
    returnVal->cssX = rawCssX/10000.0;

    rawCssY = *( (S16*) (rxBuffer + 2) );
    returnVal->cssY = rawCssY/10000.0;

    rawCssZ = *( (S16*) (rxBuffer + 4) );
    returnVal->cssZ = rawCssZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractConversionProgressTlm(uint8_t* rxBuffer, CUBEACP_ConversionProgress_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->progress = *( (U8*) (rxBuffer + 0) );

    enumVal = rxBuffer[1];
    returnVal->conversionResult = (CUBEACP_JpgConvertResult_t) enumVal;

    returnVal->outFileCounter = *( (U8*) (rxBuffer + 2) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCssConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    U8 rawCss1Scale;
    U8 rawCss2Scale;
    U8 rawCss3Scale;
    U8 rawCss4Scale;
    U8 rawCss5Scale;
    U8 rawCss6Scale;
    U8 rawCss7Scale;
    U8 rawCss8Scale;
    U8 rawCss9Scale;
    U8 rawCss10Scale;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->css1Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[1];
    returnVal->css2Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[2];
    returnVal->css3Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[3];
    returnVal->css4Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[4];
    returnVal->css5Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[5];
    returnVal->css6Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[6];
    returnVal->css7Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[7];
    returnVal->css8Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[8];
    returnVal->css9Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[9];
    returnVal->css10Conf = (CUBEACP_AxisSelect_t) enumVal;

    rawCss1Scale = *( (U8*) (rxBuffer + 10) );
    returnVal->css1Scale = rawCss1Scale*0.01;

    rawCss2Scale = *( (U8*) (rxBuffer + 11) );
    returnVal->css2Scale = rawCss2Scale*0.01;

    rawCss3Scale = *( (U8*) (rxBuffer + 12) );
    returnVal->css3Scale = rawCss3Scale*0.01;

    rawCss4Scale = *( (U8*) (rxBuffer + 13) );
    returnVal->css4Scale = rawCss4Scale*0.01;

    rawCss5Scale = *( (U8*) (rxBuffer + 14) );
    returnVal->css5Scale = rawCss5Scale*0.01;

    rawCss6Scale = *( (U8*) (rxBuffer + 15) );
    returnVal->css6Scale = rawCss6Scale*0.01;

    rawCss7Scale = *( (U8*) (rxBuffer + 16) );
    returnVal->css7Scale = rawCss7Scale*0.01;

    rawCss8Scale = *( (U8*) (rxBuffer + 17) );
    returnVal->css8Scale = rawCss8Scale*0.01;

    rawCss9Scale = *( (U8*) (rxBuffer + 18) );
    returnVal->css9Scale = rawCss9Scale*0.01;

    rawCss10Scale = *( (U8*) (rxBuffer + 19) );
    returnVal->css10Scale = rawCss10Scale*0.01;

    returnVal->cssMinimum = *( (U8*) (rxBuffer + 20) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCubeACPStateTlm(uint8_t* rxBuffer, CUBEACP_CubeACPState_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->adcsConfigLoadError = (rxBuffer[0] & 0x01) >> 0;

    returnVal->orbitParamsLoadError = (rxBuffer[0] & 0x02) >> 1;

    returnVal->systemConfigLoadError = (rxBuffer[0] & 0x04) >> 2;

    returnVal->sdInitError = (rxBuffer[0] & 0x08) >> 3;

    returnVal->sdReadError = (rxBuffer[0] & 0x10) >> 4;

    returnVal->sdWriteError = (rxBuffer[0] & 0x20) >> 5;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCubeControlCurrentsTlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    U16 rawCubeControl3V3Current;
    U16 rawCubeControl5VCurrent;
    U16 rawCubeControlBatCurrent;
    if (returnVal == 0)
        return PointerIsNull;

    rawCubeControl3V3Current = *( (U16*) (rxBuffer + 0) );
    returnVal->cubeControl3V3Current = rawCubeControl3V3Current*0.48828125;

    rawCubeControl5VCurrent = *( (U16*) (rxBuffer + 2) );
    returnVal->cubeControl5VCurrent = rawCubeControl5VCurrent*0.48828125;

    rawCubeControlBatCurrent = *( (U16*) (rxBuffer + 4) );
    returnVal->cubeControlBatCurrent = rawCubeControlBatCurrent*0.48828125;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCubeSense1CurrentsTlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    U16 rawCubeSense1_3V3Current;
    U16 rawCubeSense1_CamCurrent;
    if (returnVal == 0)
        return PointerIsNull;

    rawCubeSense1_3V3Current = *( (U16*) (rxBuffer + 0) );
    returnVal->cubeSense1_3V3Current = rawCubeSense1_3V3Current*0.1;

    rawCubeSense1_CamCurrent = *( (U16*) (rxBuffer + 2) );
    returnVal->cubeSense1_CamCurrent = rawCubeSense1_CamCurrent*0.1;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCubeSense2CurrentsTlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    U16 rawCubeSense2_3V3Current;
    U16 rawCubeSense2_CamCurrent;
    if (returnVal == 0)
        return PointerIsNull;

    rawCubeSense2_3V3Current = *( (U16*) (rxBuffer + 0) );
    returnVal->cubeSense2_3V3Current = rawCubeSense2_3V3Current*0.1;

    rawCubeSense2_CamCurrent = *( (U16*) (rxBuffer + 2) );
    returnVal->cubeSense2_CamCurrent = rawCubeSense2_CamCurrent*0.1;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCubeSenseConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawCam1Angle1;
    S16 rawCam1Angle2;
    S16 rawCam1Angle3;
    U16 rawCam1BoreX;
    U16 rawCam1BoreY;
    S16 rawCam2Angle1;
    S16 rawCam2Angle2;
    S16 rawCam2Angle3;
    U16 rawCam2BoreX;
    U16 rawCam2BoreY;
    if (returnVal == 0)
        return PointerIsNull;

    rawCam1Angle1 = *( (S16*) (rxBuffer + 0) );
    returnVal->cam1Angle1 = rawCam1Angle1*0.01;

    rawCam1Angle2 = *( (S16*) (rxBuffer + 2) );
    returnVal->cam1Angle2 = rawCam1Angle2*0.01;

    rawCam1Angle3 = *( (S16*) (rxBuffer + 4) );
    returnVal->cam1Angle3 = rawCam1Angle3*0.01;

    returnVal->cam1Threshold = *( (U8*) (rxBuffer + 6) );

    returnVal->cam1AutoAdj = (rxBuffer[7] & 0x01) >> 0;


    returnVal->cam1Exposure = *( (U16*) (rxBuffer + 8) );

    rawCam1BoreX = *( (U16*) (rxBuffer + 10) );
    returnVal->cam1BoreX = rawCam1BoreX*0.01;

    rawCam1BoreY = *( (U16*) (rxBuffer + 12) );
    returnVal->cam1BoreY = rawCam1BoreY*0.01;

    rawCam2Angle1 = *( (S16*) (rxBuffer + 14) );
    returnVal->cam2Angle1 = rawCam2Angle1*0.01;

    rawCam2Angle2 = *( (S16*) (rxBuffer + 16) );
    returnVal->cam2Angle2 = rawCam2Angle2*0.01;

    rawCam2Angle3 = *( (S16*) (rxBuffer + 18) );
    returnVal->cam2Angle3 = rawCam2Angle3*0.01;

    returnVal->cam2Threshold = *( (U8*) (rxBuffer + 20) );

    returnVal->cam2AutoAdj = (rxBuffer[21] & 0x01) >> 0;


    returnVal->cam2Exposure = *( (U16*) (rxBuffer + 22) );

    rawCam2BoreX = *( (U16*) (rxBuffer + 24) );
    returnVal->cam2BoreX = rawCam2BoreX*0.01;

    rawCam2BoreY = *( (U16*) (rxBuffer + 26) );
    returnVal->cam2BoreY = rawCam2BoreY*0.01;

    returnVal->nadirMaxDeviationPercentage = *( (U8*) (rxBuffer + 28) );

    returnVal->nadirMaxBadEdges = *( (U8*) (rxBuffer + 29) );

    returnVal->nadirMaxRadius = *( (U8*) (rxBuffer + 30) );

    returnVal->nadirMinRadius = *( (U8*) (rxBuffer + 31) );

    returnVal->cam1MaskArea1Xmin = *( (U16*) (rxBuffer + 32) );

    returnVal->cam1MaskArea1Xmax = *( (U16*) (rxBuffer + 34) );

    returnVal->cam1MaskArea1Ymin = *( (U16*) (rxBuffer + 36) );

    returnVal->cam1MaskArea1Ymax = *( (U16*) (rxBuffer + 38) );

    returnVal->cam1MaskArea2Xmin = *( (U16*) (rxBuffer + 40) );

    returnVal->cam1MaskArea2Xmax = *( (U16*) (rxBuffer + 42) );

    returnVal->cam1MaskArea2Ymin = *( (U16*) (rxBuffer + 44) );

    returnVal->cam1MaskArea2Ymax = *( (U16*) (rxBuffer + 46) );

    returnVal->cam1MaskArea3Xmin = *( (U16*) (rxBuffer + 48) );

    returnVal->cam1MaskArea3Xmax = *( (U16*) (rxBuffer + 50) );

    returnVal->cam1MaskArea3Ymin = *( (U16*) (rxBuffer + 52) );

    returnVal->cam1MaskArea3Ymax = *( (U16*) (rxBuffer + 54) );

    returnVal->cam1MaskArea4Xmin = *( (U16*) (rxBuffer + 56) );

    returnVal->cam1MaskArea4Xmax = *( (U16*) (rxBuffer + 58) );

    returnVal->cam1MaskArea4Ymin = *( (U16*) (rxBuffer + 60) );

    returnVal->cam1MaskArea4Ymax = *( (U16*) (rxBuffer + 62) );

    returnVal->cam1MaskArea5Xmin = *( (U16*) (rxBuffer + 64) );

    returnVal->cam1MaskArea5Xmax = *( (U16*) (rxBuffer + 66) );

    returnVal->cam1MaskArea5Ymin = *( (U16*) (rxBuffer + 68) );

    returnVal->cam1MaskArea5Ymax = *( (U16*) (rxBuffer + 70) );

    returnVal->cam2MaskArea1Xmin = *( (U16*) (rxBuffer + 72) );

    returnVal->cam2MaskArea1Xmax = *( (U16*) (rxBuffer + 74) );

    returnVal->cam2MaskArea1Ymin = *( (U16*) (rxBuffer + 76) );

    returnVal->cam2MaskArea1Ymax = *( (U16*) (rxBuffer + 78) );

    returnVal->cam2MaskArea2Xmin = *( (U16*) (rxBuffer + 80) );

    returnVal->cam2MaskArea2Xmax = *( (U16*) (rxBuffer + 82) );

    returnVal->cam2MaskArea2Ymin = *( (U16*) (rxBuffer + 84) );

    returnVal->cam2MaskArea2Ymax = *( (U16*) (rxBuffer + 86) );

    returnVal->cam2MaskArea3Xmin = *( (U16*) (rxBuffer + 88) );

    returnVal->cam2MaskArea3Xmax = *( (U16*) (rxBuffer + 90) );

    returnVal->cam2MaskArea3Ymin = *( (U16*) (rxBuffer + 92) );

    returnVal->cam2MaskArea3Ymax = *( (U16*) (rxBuffer + 94) );

    returnVal->cam2MaskArea4Xmin = *( (U16*) (rxBuffer + 96) );

    returnVal->cam2MaskArea4Xmax = *( (U16*) (rxBuffer + 98) );

    returnVal->cam2MaskArea4Ymin = *( (U16*) (rxBuffer + 100) );

    returnVal->cam2MaskArea4Ymax = *( (U16*) (rxBuffer + 102) );

    returnVal->cam2MaskArea5Xmin = *( (U16*) (rxBuffer + 104) );

    returnVal->cam2MaskArea5Xmax = *( (U16*) (rxBuffer + 106) );

    returnVal->cam2MaskArea5Ymin = *( (U16*) (rxBuffer + 108) );

    returnVal->cam2MaskArea5Ymax = *( (U16*) (rxBuffer + 110) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCurrentAdcsStateTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = (rxBuffer[0] >> 0) & 15;
    returnVal->estimMode = (CUBEACP_EstimModeSelect_t) enumVal;

    enumVal = (rxBuffer[0] >> 4) & 15;
    returnVal->controlMode = (CUBEACP_ConModeSelect_t) enumVal;

    enumVal = (rxBuffer[1] >> 0) & 3;
    returnVal->adcsRunMode = (CUBEACP_AdcsRunMode_t) enumVal;

    enumVal = (rxBuffer[1] >> 2) & 3;
    returnVal->asgp4Mode = (CUBEACP_Asgp4ModeSelect_t) enumVal;

    returnVal->cubeControlSignalPower = (rxBuffer[1] & 0x10) >> 4;

    returnVal->cubeControlMotorPower = (rxBuffer[1] & 0x20) >> 5;

    returnVal->cubeSense1Power = (rxBuffer[1] & 0x40) >> 6;

    returnVal->cubeSense2Power = (rxBuffer[1] & 0x80) >> 7;

    returnVal->cubeWheel1Power = (rxBuffer[2] & 0x01) >> 0;

    returnVal->cubeWheel2Power = (rxBuffer[2] & 0x02) >> 1;

    returnVal->cubeWheel3Power = (rxBuffer[2] & 0x04) >> 2;

    returnVal->cubeStarPower = (rxBuffer[2] & 0x08) >> 3;

    returnVal->gpsReceiverPower = (rxBuffer[2] & 0x10) >> 4;

    returnVal->gpsLnaPower = (rxBuffer[2] & 0x20) >> 5;

    returnVal->motorDriverPower = (rxBuffer[2] & 0x40) >> 6;

    returnVal->sunAboveHorizon = (rxBuffer[2] & 0x80) >> 7;

    returnVal->cubeSense1CommsError = (rxBuffer[3] & 0x01) >> 0;

    returnVal->cubeSense2CommsError = (rxBuffer[3] & 0x02) >> 1;

    returnVal->cubeControlSignalCommsError = (rxBuffer[3] & 0x04) >> 2;

    returnVal->cubeControlMotorCommsError = (rxBuffer[3] & 0x08) >> 3;

    returnVal->cubeWheel1CommsError = (rxBuffer[3] & 0x10) >> 4;

    returnVal->cubeWheel2CommsError = (rxBuffer[3] & 0x20) >> 5;

    returnVal->cubeWheel3CommsError = (rxBuffer[3] & 0x40) >> 6;

    returnVal->cubeStarCommsError = (rxBuffer[3] & 0x80) >> 7;

    returnVal->magRangeError = (rxBuffer[4] & 0x01) >> 0;

    returnVal->cam1OvercurrentSram = (rxBuffer[4] & 0x02) >> 1;

    returnVal->cam1Overcurrent3V3 = (rxBuffer[4] & 0x04) >> 2;

    returnVal->cam1SensNotIdle = (rxBuffer[4] & 0x08) >> 3;

    returnVal->cam1SensDetectError = (rxBuffer[4] & 0x10) >> 4;

    returnVal->sunSensRangeError = (rxBuffer[4] & 0x20) >> 5;

    returnVal->cam2OvercurrentSram = (rxBuffer[4] & 0x40) >> 6;

    returnVal->cam2Overcurrent3V3 = (rxBuffer[4] & 0x80) >> 7;

    returnVal->cam2SensNotIdle = (rxBuffer[5] & 0x01) >> 0;

    returnVal->cam2SensDetectError = (rxBuffer[5] & 0x02) >> 1;

    returnVal->nadirSensRangeError = (rxBuffer[5] & 0x04) >> 2;

    returnVal->rateSensRangeError = (rxBuffer[5] & 0x08) >> 3;

    returnVal->wheelSpeedRangeError = (rxBuffer[5] & 0x10) >> 4;

    returnVal->cssError = (rxBuffer[5] & 0x20) >> 5;

    returnVal->starMatchError = (rxBuffer[5] & 0x40) >> 6;

    returnVal->starTrackOvercurrent = (rxBuffer[5] & 0x80) >> 7;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractCurrentAdcsState2Tlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->orbitParamsInvalidError = (rxBuffer[0] & 0x01) >> 0;

    returnVal->configInvalidError = (rxBuffer[0] & 0x02) >> 1;

    returnVal->controlModeNotAllowed = (rxBuffer[0] & 0x04) >> 2;

    returnVal->estimatorNotAllowed = (rxBuffer[0] & 0x08) >> 3;

    enumVal = (rxBuffer[0] >> 4) & 3;
    returnVal->curMagMode = (CUBEACP_MagModeVal_t) enumVal;

    returnVal->magfieldModelError = (rxBuffer[0] & 0x40) >> 6;

    returnVal->nodeRecoveryError = (rxBuffer[0] & 0x80) >> 7;

    returnVal->cubeSense1RuntimeError = (rxBuffer[1] & 0x01) >> 0;

    returnVal->cubeSense2RuntimeError = (rxBuffer[1] & 0x02) >> 1;

    returnVal->cubeControlSignalRuntimeError = (rxBuffer[1] & 0x04) >> 2;

    returnVal->cubeControlMotorRuntimeError = (rxBuffer[1] & 0x08) >> 3;

    returnVal->cubeWheel1RuntimeError = (rxBuffer[1] & 0x10) >> 4;

    returnVal->cubeWheel2RuntimeError = (rxBuffer[1] & 0x20) >> 5;

    returnVal->cubeWheel3RuntimeError = (rxBuffer[1] & 0x40) >> 6;

    returnVal->cubeStarRuntimeError = (rxBuffer[1] & 0x80) >> 7;

    returnVal->magnetometerError = (rxBuffer[2] & 0x01) >> 0;

    returnVal->rateSensorFailure = (rxBuffer[2] & 0x02) >> 1;


    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractDetumbleParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawwy_ref;
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->ks = *((F32*)(rxBuffer + 0));

    returnVal->kd = *((F32*)(rxBuffer + 4));

    rawwy_ref = *( (S16*) (rxBuffer + 8) );
    returnVal->wy_ref = rawwy_ref*0.001;

    returnVal->kdf = *((F32*)(rxBuffer + 10));

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractEstimAttitudeTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    S16 rawRoll;
    S16 rawPitch;
    S16 rawYaw;
    if (returnVal == 0)
        return PointerIsNull;

    rawRoll = *( (S16*) (rxBuffer + 0) );
    returnVal->roll = rawRoll*0.01;

    rawPitch = *( (S16*) (rxBuffer + 2) );
    returnVal->pitch = rawPitch*0.01;

    rawYaw = *( (S16*) (rxBuffer + 4) );
    returnVal->yaw = rawYaw*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractEstimDataTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawIgrfMagX;
    S16 rawIgrfMagY;
    S16 rawIgrfMagZ;
    S16 rawModelSunX;
    S16 rawModelSunY;
    S16 rawModelSunZ;
    S16 rawEstimGyroBiasX;
    S16 rawEstimGyroBiasY;
    S16 rawEstimGyroBiasZ;
    S16 rawInnovX;
    S16 rawInnovY;
    S16 rawInnovZ;
    S16 rawQError1;
    S16 rawQError2;
    S16 rawQError3;
    S16 rawQCovar1;
    S16 rawQCovar2;
    S16 rawQCovar3;
    S16 rawRateCovarX;
    S16 rawRateCovarY;
    S16 rawRateCovarZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawIgrfMagX = *( (S16*) (rxBuffer + 0) );
    returnVal->igrfMagX = rawIgrfMagX*0.01;

    rawIgrfMagY = *( (S16*) (rxBuffer + 2) );
    returnVal->igrfMagY = rawIgrfMagY*0.01;

    rawIgrfMagZ = *( (S16*) (rxBuffer + 4) );
    returnVal->igrfMagZ = rawIgrfMagZ*0.01;

    rawModelSunX = *( (S16*) (rxBuffer + 6) );
    returnVal->modelSunX = rawModelSunX/10000.0;

    rawModelSunY = *( (S16*) (rxBuffer + 8) );
    returnVal->modelSunY = rawModelSunY/10000.0;

    rawModelSunZ = *( (S16*) (rxBuffer + 10) );
    returnVal->modelSunZ = rawModelSunZ/10000.0;

    rawEstimGyroBiasX = *( (S16*) (rxBuffer + 12) );
    returnVal->estimGyroBiasX = rawEstimGyroBiasX*0.001;

    rawEstimGyroBiasY = *( (S16*) (rxBuffer + 14) );
    returnVal->estimGyroBiasY = rawEstimGyroBiasY*0.001;

    rawEstimGyroBiasZ = *( (S16*) (rxBuffer + 16) );
    returnVal->estimGyroBiasZ = rawEstimGyroBiasZ*0.001;

    rawInnovX = *( (S16*) (rxBuffer + 18) );
    returnVal->innovX = rawInnovX*0.0001;

    rawInnovY = *( (S16*) (rxBuffer + 20) );
    returnVal->innovY = rawInnovY*0.0001;

    rawInnovZ = *( (S16*) (rxBuffer + 22) );
    returnVal->innovZ = rawInnovZ*0.0001;

    rawQError1 = *( (S16*) (rxBuffer + 24) );
    returnVal->qError1 = rawQError1*0.0001;

    rawQError2 = *( (S16*) (rxBuffer + 26) );
    returnVal->qError2 = rawQError2*0.0001;

    rawQError3 = *( (S16*) (rxBuffer + 28) );
    returnVal->qError3 = rawQError3*0.0001;

    rawQCovar1 = *( (S16*) (rxBuffer + 30) );
    returnVal->qCovar1 = rawQCovar1*0.001;

    rawQCovar2 = *( (S16*) (rxBuffer + 32) );
    returnVal->qCovar2 = rawQCovar2*0.001;

    rawQCovar3 = *( (S16*) (rxBuffer + 34) );
    returnVal->qCovar3 = rawQCovar3*0.001;

    rawRateCovarX = *( (S16*) (rxBuffer + 36) );
    returnVal->rateCovarX = rawRateCovarX*0.001;

    rawRateCovarY = *( (S16*) (rxBuffer + 38) );
    returnVal->rateCovarY = rawRateCovarY*0.001;

    rawRateCovarZ = *( (S16*) (rxBuffer + 40) );
    returnVal->rateCovarZ = rawRateCovarZ*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractEstimGyroBiasTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawEstimGyroBiasX;
    S16 rawEstimGyroBiasY;
    S16 rawEstimGyroBiasZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawEstimGyroBiasX = *( (S16*) (rxBuffer + 0) );
    returnVal->estimGyroBiasX = rawEstimGyroBiasX*0.001;

    rawEstimGyroBiasY = *( (S16*) (rxBuffer + 2) );
    returnVal->estimGyroBiasY = rawEstimGyroBiasY*0.001;

    rawEstimGyroBiasZ = *( (S16*) (rxBuffer + 4) );
    returnVal->estimGyroBiasZ = rawEstimGyroBiasZ*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractEstimParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->magRateNoise = *((F32*)(rxBuffer + 0));

    returnVal->ekfSysNoise = *((F32*)(rxBuffer + 4));

    returnVal->cssNoise = *((F32*)(rxBuffer + 8));

    returnVal->sunNoise = *((F32*)(rxBuffer + 12));

    returnVal->nadirNoise = *((F32*)(rxBuffer + 16));

    returnVal->magNoise = *((F32*)(rxBuffer + 20));

    returnVal->starNoise = *((F32*)(rxBuffer + 24));

    returnVal->useSunEst = (rxBuffer[28] & 0x01) >> 0;

    returnVal->useNadirEst = (rxBuffer[28] & 0x02) >> 1;

    returnVal->useCssEst = (rxBuffer[28] & 0x04) >> 2;

    returnVal->useStarEst = (rxBuffer[28] & 0x08) >> 3;

    returnVal->terminatorCheck = (rxBuffer[28] & 0x10) >> 4;

    returnVal->autoRecoverMtm = (rxBuffer[28] & 0x20) >> 5;

    enumVal = (rxBuffer[28] >> 6) & 3;
    returnVal->magMode = (CUBEACP_MagModeVal_t) enumVal;

    enumVal = (rxBuffer[29] >> 0) & 3;
    returnVal->magRawTlm2Selection = (CUBEACP_MagModeVal_t) enumVal;

    returnVal->rateSensorErrorHandling = (rxBuffer[29] & 0x04) >> 2;

    returnVal->wheelPowerOn30sDelay = (rxBuffer[29] & 0x08) >> 3;


    returnVal->cam1Cam2Period = *( (U8*) (rxBuffer + 30) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractEstimQuaternionTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->q1 = *( (S16*) (rxBuffer + 0) );

    returnVal->q2 = *( (S16*) (rxBuffer + 2) );

    returnVal->q3 = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractEstimRatesTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    S16 rawRateX;
    S16 rawRateY;
    S16 rawRateZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawRateX = *( (S16*) (rxBuffer + 0) );
    returnVal->rateX = rawRateX*0.01;

    rawRateY = *( (S16*) (rxBuffer + 2) );
    returnVal->rateY = rawRateY*0.01;

    rawRateZ = *( (S16*) (rxBuffer + 4) );
    returnVal->rateZ = rawRateZ*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractFineEstimRatesTlm(uint8_t* rxBuffer, CUBEACP_FineEstimRates_t* returnVal)
{
    S16 rawRateX;
    S16 rawRateY;
    S16 rawRateZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawRateX = *( (S16*) (rxBuffer + 0) );
    returnVal->rateX = rawRateX*0.001;

    rawRateY = *( (S16*) (rxBuffer + 2) );
    returnVal->rateY = rawRateY*0.001;

    rawRateZ = *( (S16*) (rxBuffer + 4) );
    returnVal->rateZ = rawRateZ*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractFineSunVecTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawSunX;
    S16 rawSunY;
    S16 rawSunZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawSunX = *( (S16*) (rxBuffer + 0) );
    returnVal->sunX = rawSunX/10000.0;

    rawSunY = *( (S16*) (rxBuffer + 2) );
    returnVal->sunY = rawSunY/10000.0;

    rawSunZ = *( (S16*) (rxBuffer + 4) );
    returnVal->sunZ = rawSunZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractGyroConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawXRateOffset;
    S16 rawYRateOffset;
    S16 rawZRateOffset;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->gyro1Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[1];
    returnVal->gyro2Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[2];
    returnVal->gyro3Conf = (CUBEACP_AxisSelect_t) enumVal;

    rawXRateOffset = *( (S16*) (rxBuffer + 3) );
    returnVal->xRateOffset = rawXRateOffset*0.001;

    rawYRateOffset = *( (S16*) (rxBuffer + 5) );
    returnVal->yRateOffset = rawYRateOffset*0.001;

    rawZRateOffset = *( (S16*) (rxBuffer + 7) );
    returnVal->zRateOffset = rawZRateOffset*0.001;

    returnVal->rateSensorMult = *( (U8*) (rxBuffer + 9) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractImageSaveStatusTlm(uint8_t* rxBuffer, CUBEACP_ImageSaveStatus_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->percentageComplete = *( (U8*) (rxBuffer + 0) );

    enumVal = rxBuffer[1];
    returnVal->status = (CUBEACP_ImSaveStatus_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractInertialPointReferenceTlm(uint8_t* rxBuffer, CUBEACP_InertialPointReference_t* returnVal)
{
    S16 rawInertialRefX;
    S16 rawInertialRefY;
    S16 rawInertialRefZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawInertialRefX = *( (S16*) (rxBuffer + 0) );
    returnVal->inertialRefX = rawInertialRefX/10000.0;

    rawInertialRefY = *( (S16*) (rxBuffer + 2) );
    returnVal->inertialRefY = rawInertialRefY/10000.0;

    rawInertialRefZ = *( (S16*) (rxBuffer + 4) );
    returnVal->inertialRefZ = rawInertialRefZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractInnovationVecTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawInnovX;
    S16 rawInnovY;
    S16 rawInnovZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawInnovX = *( (S16*) (rxBuffer + 0) );
    returnVal->innovX = rawInnovX*0.0001;

    rawInnovY = *( (S16*) (rxBuffer + 2) );
    returnVal->innovY = rawInnovY*0.0001;

    rawInnovZ = *( (S16*) (rxBuffer + 4) );
    returnVal->innovZ = rawInnovZ*0.0001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractLogSdConfig1Tlm(uint8_t* rxBuffer, CUBEACP_LogSdConfig1_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    memcpy(returnVal->logSelection, rxBuffer + 0, 10);

    returnVal->period = *( (U16*) (rxBuffer + 10) );

    enumVal = rxBuffer[12];
    returnVal->destination = (CUBEACP_SdLogSelect_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractLogSdConfig2Tlm(uint8_t* rxBuffer, CUBEACP_LogSdConfig2_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    memcpy(returnVal->logSelection, rxBuffer + 0, 10);

    returnVal->period = *( (U16*) (rxBuffer + 10) );

    enumVal = rxBuffer[12];
    returnVal->destination = (CUBEACP_SdLogSelect_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractLogUartConfigTlm(uint8_t* rxBuffer, CUBEACP_LogUartConfig_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    memcpy(returnVal->selection, rxBuffer + 0, 10);

    returnVal->period = *( (U16*) (rxBuffer + 10) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractMagConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawMagmAngle1;
    S16 rawMagmAngle2;
    S16 rawMagmAngle3;
    S16 rawMagmOffset1;
    S16 rawMagmOffset2;
    S16 rawMagmOffset3;
    S16 rawMagmSens11;
    S16 rawMagmSens22;
    S16 rawMagmSens33;
    S16 rawMagmSens12;
    S16 rawMagmSens13;
    S16 rawMagmSens21;
    S16 rawMagmSens23;
    S16 rawMagmSens31;
    S16 rawMagmSens32;
    if (returnVal == 0)
        return PointerIsNull;

    rawMagmAngle1 = *( (S16*) (rxBuffer + 0) );
    returnVal->magmAngle1 = rawMagmAngle1*0.01;

    rawMagmAngle2 = *( (S16*) (rxBuffer + 2) );
    returnVal->magmAngle2 = rawMagmAngle2*0.01;

    rawMagmAngle3 = *( (S16*) (rxBuffer + 4) );
    returnVal->magmAngle3 = rawMagmAngle3*0.01;

    rawMagmOffset1 = *( (S16*) (rxBuffer + 6) );
    returnVal->magmOffset1 = rawMagmOffset1*0.001;

    rawMagmOffset2 = *( (S16*) (rxBuffer + 8) );
    returnVal->magmOffset2 = rawMagmOffset2*0.001;

    rawMagmOffset3 = *( (S16*) (rxBuffer + 10) );
    returnVal->magmOffset3 = rawMagmOffset3*0.001;

    rawMagmSens11 = *( (S16*) (rxBuffer + 12) );
    returnVal->magmSens11 = rawMagmSens11*0.001;

    rawMagmSens22 = *( (S16*) (rxBuffer + 14) );
    returnVal->magmSens22 = rawMagmSens22*0.001;

    rawMagmSens33 = *( (S16*) (rxBuffer + 16) );
    returnVal->magmSens33 = rawMagmSens33*0.001;

    rawMagmSens12 = *( (S16*) (rxBuffer + 18) );
    returnVal->magmSens12 = rawMagmSens12*0.001;

    rawMagmSens13 = *( (S16*) (rxBuffer + 20) );
    returnVal->magmSens13 = rawMagmSens13*0.001;

    rawMagmSens21 = *( (S16*) (rxBuffer + 22) );
    returnVal->magmSens21 = rawMagmSens21*0.001;

    rawMagmSens23 = *( (S16*) (rxBuffer + 24) );
    returnVal->magmSens23 = rawMagmSens23*0.001;

    rawMagmSens31 = *( (S16*) (rxBuffer + 26) );
    returnVal->magmSens31 = rawMagmSens31*0.001;

    rawMagmSens32 = *( (S16*) (rxBuffer + 28) );
    returnVal->magmSens32 = rawMagmSens32*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractMagFieldTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawMagX;
    S16 rawMagY;
    S16 rawMagZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawMagX = *( (S16*) (rxBuffer + 0) );
    returnVal->magX = rawMagX*0.01;

    rawMagY = *( (S16*) (rxBuffer + 2) );
    returnVal->magY = rawMagY*0.01;

    rawMagZ = *( (S16*) (rxBuffer + 4) );
    returnVal->magZ = rawMagZ*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractMagRaw2Tlm(uint8_t* rxBuffer, CUBEACP_MagRaw2_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->magRawX = *( (S16*) (rxBuffer + 0) );

    returnVal->magRawY = *( (S16*) (rxBuffer + 2) );

    returnVal->magRawZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractMagtorqConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->magtorq1 = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[1];
    returnVal->magtorq2 = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[2];
    returnVal->magtorq3 = (CUBEACP_AxisSelect_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractMagTorquerCmdTlm(uint8_t* rxBuffer, CUBEACP_ActuatorCmd_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->torquerCmdX = *( (S16*) (rxBuffer + 0) );

    returnVal->torquerCmdY = *( (S16*) (rxBuffer + 2) );

    returnVal->torquerCmdZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractModelMagVecTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawIgrfMagX;
    S16 rawIgrfMagY;
    S16 rawIgrfMagZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawIgrfMagX = *( (S16*) (rxBuffer + 0) );
    returnVal->igrfMagX = rawIgrfMagX*0.01;

    rawIgrfMagY = *( (S16*) (rxBuffer + 2) );
    returnVal->igrfMagY = rawIgrfMagY*0.01;

    rawIgrfMagZ = *( (S16*) (rxBuffer + 4) );
    returnVal->igrfMagZ = rawIgrfMagZ*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractModelSunVecTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawModelSunX;
    S16 rawModelSunY;
    S16 rawModelSunZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawModelSunX = *( (S16*) (rxBuffer + 0) );
    returnVal->modelSunX = rawModelSunX/10000.0;

    rawModelSunY = *( (S16*) (rxBuffer + 2) );
    returnVal->modelSunY = rawModelSunY/10000.0;

    rawModelSunZ = *( (S16*) (rxBuffer + 4) );
    returnVal->modelSunZ = rawModelSunZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractMoITlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->ixx = *((F32*)(rxBuffer + 0));

    returnVal->iyy = *((F32*)(rxBuffer + 4));

    returnVal->izz = *((F32*)(rxBuffer + 8));

    returnVal->ixy = *((F32*)(rxBuffer + 12));

    returnVal->ixz = *((F32*)(rxBuffer + 16));

    returnVal->iyz = *((F32*)(rxBuffer + 20));

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractNadirVecTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawNadirX;
    S16 rawNadirY;
    S16 rawNadirZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawNadirX = *( (S16*) (rxBuffer + 0) );
    returnVal->nadirX = rawNadirX/10000.0;

    rawNadirY = *( (S16*) (rxBuffer + 2) );
    returnVal->nadirY = rawNadirY/10000.0;

    rawNadirZ = *( (S16*) (rxBuffer + 4) );
    returnVal->nadirZ = rawNadirZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractOrbitParametersTlm(uint8_t* rxBuffer, CUBEACP_OrbitParameters_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    memcpy(&returnVal->inclination, rxBuffer + 0, 8);

    memcpy(&returnVal->eccentricity, rxBuffer + 8, 8);

    memcpy(&returnVal->raan, rxBuffer + 16, 8);

    memcpy(&returnVal->argPerigee, rxBuffer + 24, 8);

    memcpy(&returnVal->bstar, rxBuffer + 32, 8);

    memcpy(&returnVal->meanMotion, rxBuffer + 40, 8);

    memcpy(&returnVal->meanAnomaly, rxBuffer + 48, 8);

    memcpy(&returnVal->epoch, rxBuffer + 56, 8);

    if ((returnVal->inclination < 0) || (returnVal->inclination > 180))
        return TlmRangeError;

    if ((returnVal->eccentricity < 0) || (returnVal->eccentricity > 1))
        return TlmRangeError;

    if ((returnVal->raan < 0) || (returnVal->raan > 360))
        return TlmRangeError;

    if ((returnVal->argPerigee < 0) || (returnVal->argPerigee > 360))
        return TlmRangeError;

    if ((returnVal->bstar < 0) || (returnVal->bstar > 1))
        return TlmRangeError;

    if ((returnVal->meanMotion < 0) || (returnVal->meanMotion > 20))
        return TlmRangeError;

    if ((returnVal->meanAnomaly < 0) || (returnVal->meanAnomaly > 360))
        return TlmRangeError;

    if ((returnVal->epoch < 0) || (returnVal->epoch > 100000))
        return TlmRangeError;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractPositionECEFTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->posEcefX = *( (S16*) (rxBuffer + 0) );

    returnVal->posEcefY = *( (S16*) (rxBuffer + 2) );

    returnVal->posEcefZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractPositionECITlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    S16 rawPositionX;
    S16 rawPositionY;
    S16 rawPositionZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawPositionX = *( (S16*) (rxBuffer + 0) );
    returnVal->positionX = rawPositionX*0.25;

    rawPositionY = *( (S16*) (rxBuffer + 2) );
    returnVal->positionY = rawPositionY*0.25;

    rawPositionZ = *( (S16*) (rxBuffer + 4) );
    returnVal->positionZ = rawPositionZ*0.25;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractPositionLLHTlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    S16 rawLatitude;
    S16 rawLongitude;
    U16 rawAltitude;
    if (returnVal == 0)
        return PointerIsNull;

    rawLatitude = *( (S16*) (rxBuffer + 0) );
    returnVal->latitude = rawLatitude*0.01;

    rawLongitude = *( (S16*) (rxBuffer + 2) );
    returnVal->longitude = rawLongitude*0.01;

    rawAltitude = *( (U16*) (rxBuffer + 4) );
    returnVal->altitude = rawAltitude*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractQuaternionCovarTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawQCovar1;
    S16 rawQCovar2;
    S16 rawQCovar3;
    if (returnVal == 0)
        return PointerIsNull;

    rawQCovar1 = *( (S16*) (rxBuffer + 0) );
    returnVal->qCovar1 = rawQCovar1*0.001;

    rawQCovar2 = *( (S16*) (rxBuffer + 2) );
    returnVal->qCovar2 = rawQCovar2*0.001;

    rawQCovar3 = *( (S16*) (rxBuffer + 4) );
    returnVal->qCovar3 = rawQCovar3*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractQuaternionErrVecTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawQError1;
    S16 rawQError2;
    S16 rawQError3;
    if (returnVal == 0)
        return PointerIsNull;

    rawQError1 = *( (S16*) (rxBuffer + 0) );
    returnVal->qError1 = rawQError1*0.0001;

    rawQError2 = *( (S16*) (rxBuffer + 2) );
    returnVal->qError2 = rawQError2*0.0001;

    rawQError3 = *( (S16*) (rxBuffer + 4) );
    returnVal->qError3 = rawQError3*0.0001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRateCovarTlm(uint8_t* rxBuffer, CUBEACP_EstimData_t* returnVal)
{
    S16 rawRateCovarX;
    S16 rawRateCovarY;
    S16 rawRateCovarZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawRateCovarX = *( (S16*) (rxBuffer + 0) );
    returnVal->rateCovarX = rawRateCovarX*0.001;

    rawRateCovarY = *( (S16*) (rxBuffer + 2) );
    returnVal->rateCovarY = rawRateCovarY*0.001;

    rawRateCovarZ = *( (S16*) (rxBuffer + 4) );
    returnVal->rateCovarZ = rawRateCovarZ*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRateSensorTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawRateX;
    S16 rawRateY;
    S16 rawRateZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawRateX = *( (S16*) (rxBuffer + 0) );
    returnVal->rateX = rawRateX*0.01;

    rawRateY = *( (S16*) (rxBuffer + 2) );
    returnVal->rateY = rawRateY*0.01;

    rawRateZ = *( (S16*) (rxBuffer + 4) );
    returnVal->rateZ = rawRateZ*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawCam1SensTlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->cam1RawX = *( (S16*) (rxBuffer + 0) );

    returnVal->cam1RawY = *( (S16*) (rxBuffer + 2) );

    enumVal = rxBuffer[4];
    returnVal->cam1Busy = (CUBEACP_CaptureResult_t) enumVal;

    enumVal = rxBuffer[5];
    returnVal->cam1Result = (CUBEACP_DetectResult_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawCam2SensTlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->cam2RawX = *( (S16*) (rxBuffer + 0) );

    returnVal->cam2RawY = *( (S16*) (rxBuffer + 2) );

    enumVal = rxBuffer[4];
    returnVal->cam2Busy = (CUBEACP_CaptureResult_t) enumVal;

    enumVal = rxBuffer[5];
    returnVal->cam2Result = (CUBEACP_DetectResult_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawCss1Tlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->cssRaw1 = *( (U8*) (rxBuffer + 0) );

    returnVal->cssRaw2 = *( (U8*) (rxBuffer + 1) );

    returnVal->cssRaw3 = *( (U8*) (rxBuffer + 2) );

    returnVal->cssRaw4 = *( (U8*) (rxBuffer + 3) );

    returnVal->cssRaw5 = *( (U8*) (rxBuffer + 4) );

    returnVal->cssRaw6 = *( (U8*) (rxBuffer + 5) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawCss2Tlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->cssRaw7 = *( (U8*) (rxBuffer + 0) );

    returnVal->cssRaw8 = *( (U8*) (rxBuffer + 1) );

    returnVal->cssRaw9 = *( (U8*) (rxBuffer + 2) );

    returnVal->cssRaw10 = *( (U8*) (rxBuffer + 3) );

    returnVal->magRawX = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawGPSTlm(uint8_t* rxBuffer, CUBEACP_RawGPS_t* returnVal)
{
    U8 rawStdDevPosX;
    U8 rawStdDevPosY;
    U8 rawStdDevPosZ;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->gpsSolutionStatus = (CUBEACP_GpsSolutionStatus_t) enumVal;

    returnVal->gpsNumSatsTracked = *( (U8*) (rxBuffer + 1) );

    returnVal->gpsNumSatsSolution = *( (U8*) (rxBuffer + 2) );

    returnVal->gpsXYZLogCtr = *( (U8*) (rxBuffer + 3) );

    returnVal->gpsRangeLogCtr = *( (U8*) (rxBuffer + 4) );

    returnVal->gpsResponse = *( (U8*) (rxBuffer + 5) );

    returnVal->gpsWeek = *( (U16*) (rxBuffer + 6) );

    returnVal->gpsTimeMs = *( (U32*) (rxBuffer + 8) );

    returnVal->posEcefX = *( (S32*) (rxBuffer + 12) );

    returnVal->velEcefX = *( (S16*) (rxBuffer + 16) );

    returnVal->posEcefY = *( (S32*) (rxBuffer + 18) );

    returnVal->velEcefY = *( (S16*) (rxBuffer + 22) );

    returnVal->posEcefZ = *( (S32*) (rxBuffer + 24) );

    returnVal->velEcefZ = *( (S16*) (rxBuffer + 28) );

    rawStdDevPosX = *( (U8*) (rxBuffer + 30) );
    returnVal->stdDevPosX = rawStdDevPosX*0.1;

    rawStdDevPosY = *( (U8*) (rxBuffer + 31) );
    returnVal->stdDevPosY = rawStdDevPosY*0.1;

    rawStdDevPosZ = *( (U8*) (rxBuffer + 32) );
    returnVal->stdDevPosZ = rawStdDevPosZ*0.1;

    returnVal->stdDevVelX = *( (U8*) (rxBuffer + 33) );

    returnVal->stdDevVelY = *( (U8*) (rxBuffer + 34) );

    returnVal->stdDevVelZ = *( (U8*) (rxBuffer + 35) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawGpsStatusTlm(uint8_t* rxBuffer, CUBEACP_RawGPS_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->gpsSolutionStatus = (CUBEACP_GpsSolutionStatus_t) enumVal;

    returnVal->gpsNumSatsTracked = *( (U8*) (rxBuffer + 1) );

    returnVal->gpsNumSatsSolution = *( (U8*) (rxBuffer + 2) );

    returnVal->gpsXYZLogCtr = *( (U8*) (rxBuffer + 3) );

    returnVal->gpsRangeLogCtr = *( (U8*) (rxBuffer + 4) );

    returnVal->gpsResponse = *( (U8*) (rxBuffer + 5) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawGpsTimeTlm(uint8_t* rxBuffer, CUBEACP_RawGPS_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->gpsWeek = *( (U16*) (rxBuffer + 0) );

    returnVal->gpsTimeMs = *( (U32*) (rxBuffer + 2) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawGpsXTlm(uint8_t* rxBuffer, CUBEACP_RawGPS_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->posEcefX = *( (S32*) (rxBuffer + 0) );

    returnVal->velEcefX = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawGpsYTlm(uint8_t* rxBuffer, CUBEACP_RawGPS_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->posEcefY = *( (S32*) (rxBuffer + 0) );

    returnVal->velEcefY = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawGpsZTlm(uint8_t* rxBuffer, CUBEACP_RawGPS_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->posEcefZ = *( (S32*) (rxBuffer + 0) );

    returnVal->velEcefZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawMagnetometerTlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->magRawX = *( (S16*) (rxBuffer + 0) );

    returnVal->magRawY = *( (S16*) (rxBuffer + 2) );

    returnVal->magRawZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawRateTlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->rawRateX = *( (S16*) (rxBuffer + 0) );

    returnVal->rawRateY = *( (S16*) (rxBuffer + 2) );

    returnVal->rawRateZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawSensorTlm(uint8_t* rxBuffer, CUBEACP_RawSensor_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->cam2RawX = *( (S16*) (rxBuffer + 0) );

    returnVal->cam2RawY = *( (S16*) (rxBuffer + 2) );

    enumVal = rxBuffer[4];
    returnVal->cam2Busy = (CUBEACP_CaptureResult_t) enumVal;

    enumVal = rxBuffer[5];
    returnVal->cam2Result = (CUBEACP_DetectResult_t) enumVal;

    returnVal->cam1RawX = *( (S16*) (rxBuffer + 6) );

    returnVal->cam1RawY = *( (S16*) (rxBuffer + 8) );

    enumVal = rxBuffer[10];
    returnVal->cam1Busy = (CUBEACP_CaptureResult_t) enumVal;

    enumVal = rxBuffer[11];
    returnVal->cam1Result = (CUBEACP_DetectResult_t) enumVal;

    returnVal->cssRaw1 = *( (U8*) (rxBuffer + 12) );

    returnVal->cssRaw2 = *( (U8*) (rxBuffer + 13) );

    returnVal->cssRaw3 = *( (U8*) (rxBuffer + 14) );

    returnVal->cssRaw4 = *( (U8*) (rxBuffer + 15) );

    returnVal->cssRaw5 = *( (U8*) (rxBuffer + 16) );

    returnVal->cssRaw6 = *( (U8*) (rxBuffer + 17) );

    returnVal->cssRaw7 = *( (U8*) (rxBuffer + 18) );

    returnVal->cssRaw8 = *( (U8*) (rxBuffer + 19) );

    returnVal->cssRaw9 = *( (U8*) (rxBuffer + 20) );

    returnVal->cssRaw10 = *( (U8*) (rxBuffer + 21) );

    returnVal->magRawX = *( (S16*) (rxBuffer + 22) );

    returnVal->magRawY = *( (S16*) (rxBuffer + 24) );

    returnVal->magRawZ = *( (S16*) (rxBuffer + 26) );

    returnVal->rawRateX = *( (S16*) (rxBuffer + 28) );

    returnVal->rawRateY = *( (S16*) (rxBuffer + 30) );

    returnVal->rawRateZ = *( (S16*) (rxBuffer + 32) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRawStarTrackerTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    S16 rawStarRateX;
    S16 rawStarRateY;
    S16 rawStarRateZ;
    S16 rawStarQbar0;
    S16 rawStarQbar1;
    S16 rawStarQbar2;
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->numStarsDetected = *( (U8*) (rxBuffer + 0) );

    returnVal->starImageNoise = *( (U8*) (rxBuffer + 1) );

    returnVal->invalidStars = *( (U8*) (rxBuffer + 2) );

    returnVal->numberOfStarsID = *( (U8*) (rxBuffer + 3) );

    enumVal = rxBuffer[4];
    returnVal->iDmode = (CUBEACP_StarIDModeVal_t) enumVal;

    returnVal->imageDarkValue = *( (U8*) (rxBuffer + 5) );

    returnVal->imageCaptureSuccess = (rxBuffer[6] & 0x01) >> 0;

    returnVal->detectionSuccess = (rxBuffer[6] & 0x02) >> 1;

    returnVal->identificationSuccess = (rxBuffer[6] & 0x04) >> 2;

    returnVal->attitudeSuccess = (rxBuffer[6] & 0x08) >> 3;

    returnVal->processingTimeError = (rxBuffer[6] & 0x10) >> 4;

    returnVal->trackingModuleEnabled = (rxBuffer[6] & 0x20) >> 5;

    returnVal->predictionEnabled = (rxBuffer[6] & 0x40) >> 6;

    returnVal->commsError = (rxBuffer[6] & 0x80) >> 7;

    returnVal->deltaT = *( (U16*) (rxBuffer + 7) );

    returnVal->s1Conf = *( (U8*) (rxBuffer + 9) );

    returnVal->s2Conf = *( (U8*) (rxBuffer + 10) );

    returnVal->s3Conf = *( (U8*) (rxBuffer + 11) );

    returnVal->magStar1 = *( (U16*) (rxBuffer + 12) );

    returnVal->magStar2 = *( (U16*) (rxBuffer + 14) );

    returnVal->magStar3 = *( (U16*) (rxBuffer + 16) );

    returnVal->catStar1 = *( (U16*) (rxBuffer + 18) );

    returnVal->centXStar1 = *( (S16*) (rxBuffer + 20) );

    returnVal->centYStar1 = *( (S16*) (rxBuffer + 22) );

    returnVal->catStar2 = *( (U16*) (rxBuffer + 24) );

    returnVal->centXStar2 = *( (S16*) (rxBuffer + 26) );

    returnVal->centYStar2 = *( (S16*) (rxBuffer + 28) );

    returnVal->catStar3 = *( (U16*) (rxBuffer + 30) );

    returnVal->centXStar3 = *( (S16*) (rxBuffer + 32) );

    returnVal->centYStar3 = *( (S16*) (rxBuffer + 34) );

    returnVal->capture = *( (U16*) (rxBuffer + 36) );

    returnVal->detection = *( (U16*) (rxBuffer + 38) );

    returnVal->identification = *( (U16*) (rxBuffer + 40) );

    rawStarRateX = *( (S16*) (rxBuffer + 42) );
    returnVal->starRateX = rawStarRateX/10000.0;

    rawStarRateY = *( (S16*) (rxBuffer + 44) );
    returnVal->starRateY = rawStarRateY/10000.0;

    rawStarRateZ = *( (S16*) (rxBuffer + 46) );
    returnVal->starRateZ = rawStarRateZ/10000.0;

    rawStarQbar0 = *( (S16*) (rxBuffer + 48) );
    returnVal->starQbar0 = rawStarQbar0/10000.0;

    rawStarQbar1 = *( (S16*) (rxBuffer + 50) );
    returnVal->starQbar1 = rawStarQbar1/10000.0;

    rawStarQbar2 = *( (S16*) (rxBuffer + 52) );
    returnVal->starQbar2 = rawStarQbar2/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRedMagConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawMredAngle1;
    S16 rawMredAngle2;
    S16 rawMredAngle3;
    S16 rawMredOffset1;
    S16 rawMredOffset2;
    S16 rawMredOffset3;
    S16 rawMredSens11;
    S16 rawMredSens22;
    S16 rawMredSens33;
    S16 rawMredSens12;
    S16 rawMredSens13;
    S16 rawMredSens21;
    S16 rawMredSens23;
    S16 rawMredSens31;
    S16 rawMredSens32;
    if (returnVal == 0)
        return PointerIsNull;

    rawMredAngle1 = *( (S16*) (rxBuffer + 0) );
    returnVal->mredAngle1 = rawMredAngle1*0.01;

    rawMredAngle2 = *( (S16*) (rxBuffer + 2) );
    returnVal->mredAngle2 = rawMredAngle2*0.01;

    rawMredAngle3 = *( (S16*) (rxBuffer + 4) );
    returnVal->mredAngle3 = rawMredAngle3*0.01;

    rawMredOffset1 = *( (S16*) (rxBuffer + 6) );
    returnVal->mredOffset1 = rawMredOffset1*0.001;

    rawMredOffset2 = *( (S16*) (rxBuffer + 8) );
    returnVal->mredOffset2 = rawMredOffset2*0.001;

    rawMredOffset3 = *( (S16*) (rxBuffer + 10) );
    returnVal->mredOffset3 = rawMredOffset3*0.001;

    rawMredSens11 = *( (S16*) (rxBuffer + 12) );
    returnVal->mredSens11 = rawMredSens11*0.001;

    rawMredSens22 = *( (S16*) (rxBuffer + 14) );
    returnVal->mredSens22 = rawMredSens22*0.001;

    rawMredSens33 = *( (S16*) (rxBuffer + 16) );
    returnVal->mredSens33 = rawMredSens33*0.001;

    rawMredSens12 = *( (S16*) (rxBuffer + 18) );
    returnVal->mredSens12 = rawMredSens12*0.001;

    rawMredSens13 = *( (S16*) (rxBuffer + 20) );
    returnVal->mredSens13 = rawMredSens13*0.001;

    rawMredSens21 = *( (S16*) (rxBuffer + 22) );
    returnVal->mredSens21 = rawMredSens21*0.001;

    rawMredSens23 = *( (S16*) (rxBuffer + 24) );
    returnVal->mredSens23 = rawMredSens23*0.001;

    rawMredSens31 = *( (S16*) (rxBuffer + 26) );
    returnVal->mredSens31 = rawMredSens31*0.001;

    rawMredSens32 = *( (S16*) (rxBuffer + 28) );
    returnVal->mredSens32 = rawMredSens32*0.001;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractRWheelParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->kp2 = *((F32*)(rxBuffer + 0));

    returnVal->kd2 = *((F32*)(rxBuffer + 4));

    returnVal->h_bias = *((F32*)(rxBuffer + 8));

    enumVal = (rxBuffer[12] >> 0) & 127;
    returnVal->sunPointFacet = (CUBEACP_AxisSelect_t) enumVal;

    returnVal->wheelErrorHandling = (rxBuffer[12] & 0x80) >> 7;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractSpeedCmdTlm(uint8_t* rxBuffer, CUBEACP_ActuatorCmd_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->speedCmdX = *( (S16*) (rxBuffer + 0) );

    returnVal->speedCmdY = *( (S16*) (rxBuffer + 2) );

    returnVal->speedCmdZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar1BodyTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawStar1BX;
    S16 rawStar1BY;
    S16 rawStar1BZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStar1BX = *( (S16*) (rxBuffer + 0) );
    returnVal->star1BX = rawStar1BX/10000.0;

    rawStar1BY = *( (S16*) (rxBuffer + 2) );
    returnVal->star1BY = rawStar1BY/10000.0;

    rawStar1BZ = *( (S16*) (rxBuffer + 4) );
    returnVal->star1BZ = rawStar1BZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar1OrbitTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawStar1OX;
    S16 rawStar1OY;
    S16 rawStar1OZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStar1OX = *( (S16*) (rxBuffer + 0) );
    returnVal->star1OX = rawStar1OX/10000.0;

    rawStar1OY = *( (S16*) (rxBuffer + 2) );
    returnVal->star1OY = rawStar1OY/10000.0;

    rawStar1OZ = *( (S16*) (rxBuffer + 4) );
    returnVal->star1OZ = rawStar1OZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar1RawTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->catStar1 = *( (U16*) (rxBuffer + 0) );

    returnVal->centXStar1 = *( (S16*) (rxBuffer + 2) );

    returnVal->centYStar1 = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar2BodyTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawStar2BX;
    S16 rawStar2BY;
    S16 rawStar2BZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStar2BX = *( (S16*) (rxBuffer + 0) );
    returnVal->star2BX = rawStar2BX/10000.0;

    rawStar2BY = *( (S16*) (rxBuffer + 2) );
    returnVal->star2BY = rawStar2BY/10000.0;

    rawStar2BZ = *( (S16*) (rxBuffer + 4) );
    returnVal->star2BZ = rawStar2BZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar2OrbitTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawStar2OX;
    S16 rawStar2OY;
    S16 rawStar2OZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStar2OX = *( (S16*) (rxBuffer + 0) );
    returnVal->star2OX = rawStar2OX/10000.0;

    rawStar2OY = *( (S16*) (rxBuffer + 2) );
    returnVal->star2OY = rawStar2OY/10000.0;

    rawStar2OZ = *( (S16*) (rxBuffer + 4) );
    returnVal->star2OZ = rawStar2OZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar2RawTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->catStar2 = *( (U16*) (rxBuffer + 0) );

    returnVal->centXStar2 = *( (S16*) (rxBuffer + 2) );

    returnVal->centYStar2 = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar3BodyTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawStar3BX;
    S16 rawStar3BY;
    S16 rawStar3BZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStar3BX = *( (S16*) (rxBuffer + 0) );
    returnVal->star3BX = rawStar3BX/10000.0;

    rawStar3BY = *( (S16*) (rxBuffer + 2) );
    returnVal->star3BY = rawStar3BY/10000.0;

    rawStar3BZ = *( (S16*) (rxBuffer + 4) );
    returnVal->star3BZ = rawStar3BZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar3OrbitTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    S16 rawStar3OX;
    S16 rawStar3OY;
    S16 rawStar3OZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStar3OX = *( (S16*) (rxBuffer + 0) );
    returnVal->star3OX = rawStar3OX/10000.0;

    rawStar3OY = *( (S16*) (rxBuffer + 2) );
    returnVal->star3OY = rawStar3OY/10000.0;

    rawStar3OZ = *( (S16*) (rxBuffer + 4) );
    returnVal->star3OZ = rawStar3OZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStar3RawTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->catStar3 = *( (U16*) (rxBuffer + 0) );

    returnVal->centXStar3 = *( (S16*) (rxBuffer + 2) );

    returnVal->centYStar3 = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    S16 rawStarAngle1;
    S16 rawStarAngle2;
    S16 rawStarAngle3;
    U8 rawStarErrorMargin;
    U8 rawStarTrackingMargin;
    U8 rawStarValidationMargin;
    U8 rawStarSearchWidth;
    if (returnVal == 0)
        return PointerIsNull;

    rawStarAngle1 = *( (S16*) (rxBuffer + 0) );
    returnVal->starAngle1 = rawStarAngle1*0.01;

    rawStarAngle2 = *( (S16*) (rxBuffer + 2) );
    returnVal->starAngle2 = rawStarAngle2*0.01;

    rawStarAngle3 = *( (S16*) (rxBuffer + 4) );
    returnVal->starAngle3 = rawStarAngle3*0.01;

    returnVal->starExposure = *( (U16*) (rxBuffer + 6) );

    returnVal->starGain = *( (U16*) (rxBuffer + 8) );

    returnVal->detectionThreshold = *( (U8*) (rxBuffer + 10) );

    returnVal->starThreshold = *( (U8*) (rxBuffer + 11) );

    returnVal->maxStarMatched = *( (U8*) (rxBuffer + 12) );

    returnVal->starTimeoutTime = *( (U16*) (rxBuffer + 13) );

    returnVal->maxStarPixel = *( (U8*) (rxBuffer + 15) );

    returnVal->minStarPixel = *( (U8*) (rxBuffer + 16) );

    rawStarErrorMargin = *( (U8*) (rxBuffer + 17) );
    returnVal->starErrorMargin = rawStarErrorMargin*0.01;

    returnVal->starDelayTime = *( (U16*) (rxBuffer + 18) );

    returnVal->starCentX = *((F32*)(rxBuffer + 20));

    returnVal->starCentY = *((F32*)(rxBuffer + 24));

    returnVal->starFocal = *((F32*)(rxBuffer + 28));

    returnVal->starLensK1 = *((F32*)(rxBuffer + 32));

    returnVal->starLensK2 = *((F32*)(rxBuffer + 36));

    returnVal->starLensP1 = *((F32*)(rxBuffer + 40));

    returnVal->starLensP2 = *((F32*)(rxBuffer + 44));

    returnVal->starWindowWidth = *( (U8*) (rxBuffer + 48) );

    rawStarTrackingMargin = *( (U8*) (rxBuffer + 49) );
    returnVal->starTrackingMargin = rawStarTrackingMargin/100.0;

    rawStarValidationMargin = *( (U8*) (rxBuffer + 50) );
    returnVal->starValidationMargin = rawStarValidationMargin/100.0;

    returnVal->starModuleEnable = (rxBuffer[51] & 0x01) >> 0;

    returnVal->starLocationPredictionEnable = (rxBuffer[51] & 0x02) >> 1;


    rawStarSearchWidth = *( (U8*) (rxBuffer + 52) );
    returnVal->starSearchWidth = rawStarSearchWidth/5.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarEstimQTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    S16 rawStarQbar0;
    S16 rawStarQbar1;
    S16 rawStarQbar2;
    if (returnVal == 0)
        return PointerIsNull;

    rawStarQbar0 = *( (S16*) (rxBuffer + 0) );
    returnVal->starQbar0 = rawStarQbar0/10000.0;

    rawStarQbar1 = *( (S16*) (rxBuffer + 2) );
    returnVal->starQbar1 = rawStarQbar1/10000.0;

    rawStarQbar2 = *( (S16*) (rxBuffer + 4) );
    returnVal->starQbar2 = rawStarQbar2/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarEstimRateTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    S16 rawStarRateX;
    S16 rawStarRateY;
    S16 rawStarRateZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawStarRateX = *( (S16*) (rxBuffer + 0) );
    returnVal->starRateX = rawStarRateX/10000.0;

    rawStarRateY = *( (S16*) (rxBuffer + 2) );
    returnVal->starRateY = rawStarRateY/10000.0;

    rawStarRateZ = *( (S16*) (rxBuffer + 4) );
    returnVal->starRateZ = rawStarRateZ/10000.0;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarMagnitudeTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->magStar1 = *( (U16*) (rxBuffer + 0) );

    returnVal->magStar2 = *( (U16*) (rxBuffer + 2) );

    returnVal->magStar3 = *( (U16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarPerformance1Tlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->numStarsDetected = *( (U8*) (rxBuffer + 0) );

    returnVal->starImageNoise = *( (U8*) (rxBuffer + 1) );

    returnVal->invalidStars = *( (U8*) (rxBuffer + 2) );

    returnVal->numberOfStarsID = *( (U8*) (rxBuffer + 3) );

    enumVal = rxBuffer[4];
    returnVal->iDmode = (CUBEACP_StarIDModeVal_t) enumVal;

    returnVal->imageDarkValue = *( (U8*) (rxBuffer + 5) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarPerformance2Tlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->imageCaptureSuccess = (rxBuffer[0] & 0x01) >> 0;

    returnVal->detectionSuccess = (rxBuffer[0] & 0x02) >> 1;

    returnVal->identificationSuccess = (rxBuffer[0] & 0x04) >> 2;

    returnVal->attitudeSuccess = (rxBuffer[0] & 0x08) >> 3;

    returnVal->processingTimeError = (rxBuffer[0] & 0x10) >> 4;

    returnVal->trackingModuleEnabled = (rxBuffer[0] & 0x20) >> 5;

    returnVal->predictionEnabled = (rxBuffer[0] & 0x40) >> 6;

    returnVal->commsError = (rxBuffer[0] & 0x80) >> 7;

    returnVal->deltaT = *( (U16*) (rxBuffer + 1) );

    returnVal->s1Conf = *( (U8*) (rxBuffer + 3) );

    returnVal->s2Conf = *( (U8*) (rxBuffer + 4) );

    returnVal->s3Conf = *( (U8*) (rxBuffer + 5) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractStarTimingTlm(uint8_t* rxBuffer, CUBEACP_RawStarTracker_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->capture = *( (U16*) (rxBuffer + 0) );

    returnVal->detection = *( (U16*) (rxBuffer + 2) );

    returnVal->identification = *( (U16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractTrackingParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    returnVal->kp3 = *((F32*)(rxBuffer + 0));

    returnVal->kd3 = *((F32*)(rxBuffer + 4));

    returnVal->ki3 = *((F32*)(rxBuffer + 8));

    enumVal = rxBuffer[12];
    returnVal->targetTrackFacet = (CUBEACP_AxisSelect_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractUserConEstParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    memcpy(returnVal->userConSettings, rxBuffer + 0, 48);

    memcpy(returnVal->userEstSettings, rxBuffer + 48, 48);

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractVelocityECITlm(uint8_t* rxBuffer, CUBEACP_AdcsState_t* returnVal)
{
    S16 rawVelocityX;
    S16 rawVelocityY;
    S16 rawVelocityZ;
    if (returnVal == 0)
        return PointerIsNull;

    rawVelocityX = *( (S16*) (rxBuffer + 0) );
    returnVal->velocityX = rawVelocityX*0.25;

    rawVelocityY = *( (S16*) (rxBuffer + 2) );
    returnVal->velocityY = rawVelocityY*0.25;

    rawVelocityZ = *( (S16*) (rxBuffer + 4) );
    returnVal->velocityZ = rawVelocityZ*0.25;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractWheelConfigTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    uint8_t enumVal;

    if (returnVal == 0)
        return PointerIsNull;

    enumVal = rxBuffer[0];
    returnVal->rW1Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[1];
    returnVal->rW2Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[2];
    returnVal->rW3Conf = (CUBEACP_AxisSelect_t) enumVal;

    enumVal = rxBuffer[3];
    returnVal->rW4Conf = (CUBEACP_AxisSelect_t) enumVal;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractWheelCurrentsTlm(uint8_t* rxBuffer, CUBEACP_AdcsPowerMeasure_t* returnVal)
{
    U16 rawWheel1Current;
    U16 rawWheel2Current;
    U16 rawWheel3Current;
    if (returnVal == 0)
        return PointerIsNull;

    rawWheel1Current = *( (U16*) (rxBuffer + 0) );
    returnVal->wheel1Current = rawWheel1Current*0.01;

    rawWheel2Current = *( (U16*) (rxBuffer + 2) );
    returnVal->wheel2Current = rawWheel2Current*0.01;

    rawWheel3Current = *( (U16*) (rxBuffer + 4) );
    returnVal->wheel3Current = rawWheel3Current*0.01;

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractWheelSpeedTlm(uint8_t* rxBuffer, CUBEACP_AdcsMeasure_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->speedX = *( (S16*) (rxBuffer + 0) );

    returnVal->speedY = *( (S16*) (rxBuffer + 2) );

    returnVal->speedZ = *( (S16*) (rxBuffer + 4) );

    return CubeLibOk;
}

CUBEADCS_Result_t CUBEACP_ExtractYWheelParamsTlm(uint8_t* rxBuffer, CUBEACP_AdcsConfig_t* returnVal)
{
    if (returnVal == 0)
        return PointerIsNull;

    returnVal->kh = *((F32*)(rxBuffer + 0));

    returnVal->kn = *((F32*)(rxBuffer + 4));

    returnVal->kp1 = *((F32*)(rxBuffer + 8));

    returnVal->kd1 = *((F32*)(rxBuffer + 12));

    returnVal->h_ref = *((F32*)(rxBuffer + 16));

    return CubeLibOk;
}


uint16_t CUBEACP_FormatAdcsConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 20;

    tcBuffer[1] = 
        (setVal->magtorq1 << 0);
    tcBuffer[2] = 
        (setVal->magtorq2 << 0);
    tcBuffer[3] = 
        (setVal->magtorq3 << 0);
    tcBuffer[4] = 
        (setVal->rW1Conf << 0);
    tcBuffer[5] = 
        (setVal->rW2Conf << 0);
    tcBuffer[6] = 
        (setVal->rW3Conf << 0);
    tcBuffer[7] = 
        (setVal->rW4Conf << 0);
    tcBuffer[8] = 
        (setVal->gyro1Conf << 0);
    tcBuffer[9] = 
        (setVal->gyro2Conf << 0);
    tcBuffer[10] = 
        (setVal->gyro3Conf << 0);
    tcBuffer[18] = 
        (setVal->css1Conf << 0);
    tcBuffer[19] = 
        (setVal->css2Conf << 0);
    tcBuffer[20] = 
        (setVal->css3Conf << 0);
    tcBuffer[21] = 
        (setVal->css4Conf << 0);
    tcBuffer[22] = 
        (setVal->css5Conf << 0);
    tcBuffer[23] = 
        (setVal->css6Conf << 0);
    tcBuffer[24] = 
        (setVal->css7Conf << 0);
    tcBuffer[25] = 
        (setVal->css8Conf << 0);
    tcBuffer[26] = 
        (setVal->css9Conf << 0);
    tcBuffer[27] = 
        (setVal->css10Conf << 0);
    tcBuffer[46] = 
        (setVal->cam1AutoAdj << 0);
    tcBuffer[60] = 
        (setVal->cam2AutoAdj << 0);
    tcBuffer[262] = 
        (setVal->starModuleEnable << 0) + 
        (setVal->starLocationPredictionEnable << 1);
    tcBuffer[310] = 
        (setVal->sunPointFacet << 0) + 
        (setVal->wheelErrorHandling << 7);
    tcBuffer[323] = 
        (setVal->targetTrackFacet << 0);
    tcBuffer[376] = 
        (setVal->useSunEst << 0) + 
        (setVal->useNadirEst << 1) + 
        (setVal->useCssEst << 2) + 
        (setVal->useStarEst << 3) + 
        (setVal->terminatorCheck << 4) + 
        (setVal->autoRecoverMtm << 5) + 
        (setVal->magMode << 6);
    tcBuffer[377] = 
        (setVal->magRawTlm2Selection << 0) + 
        (setVal->rateSensorErrorHandling << 2) + 
        (setVal->wheelPowerOn30sDelay << 3);
    tcBuffer[392] = 
        (setVal->asgp4Filter << 0);
    *( (S16*)(tcBuffer + 11) ) = (S16) round(setVal->xRateOffset*1000.0);
    *( (S16*)(tcBuffer + 13) ) = (S16) round(setVal->yRateOffset*1000.0);
    *( (S16*)(tcBuffer + 15) ) = (S16) round(setVal->zRateOffset*1000.0);
    *( (U8*)(tcBuffer + 17) ) = setVal->rateSensorMult;
    *( (U8*)(tcBuffer + 28) ) = (U8) round(setVal->css1Scale*100.0);
    *( (U8*)(tcBuffer + 29) ) = (U8) round(setVal->css2Scale*100.0);
    *( (U8*)(tcBuffer + 30) ) = (U8) round(setVal->css3Scale*100.0);
    *( (U8*)(tcBuffer + 31) ) = (U8) round(setVal->css4Scale*100.0);
    *( (U8*)(tcBuffer + 32) ) = (U8) round(setVal->css5Scale*100.0);
    *( (U8*)(tcBuffer + 33) ) = (U8) round(setVal->css6Scale*100.0);
    *( (U8*)(tcBuffer + 34) ) = (U8) round(setVal->css7Scale*100.0);
    *( (U8*)(tcBuffer + 35) ) = (U8) round(setVal->css8Scale*100.0);
    *( (U8*)(tcBuffer + 36) ) = (U8) round(setVal->css9Scale*100.0);
    *( (U8*)(tcBuffer + 37) ) = (U8) round(setVal->css10Scale*100.0);
    *( (U8*)(tcBuffer + 38) ) = setVal->cssMinimum;
    *( (S16*)(tcBuffer + 39) ) = (S16) round(setVal->cam1Angle1*100.0);
    *( (S16*)(tcBuffer + 41) ) = (S16) round(setVal->cam1Angle2*100.0);
    *( (S16*)(tcBuffer + 43) ) = (S16) round(setVal->cam1Angle3*100.0);
    *( (U8*)(tcBuffer + 45) ) = setVal->cam1Threshold;
    *( (U16*)(tcBuffer + 47) ) = setVal->cam1Exposure;
    *( (U16*)(tcBuffer + 49) ) = (U16) round(setVal->cam1BoreX*100.0);
    *( (U16*)(tcBuffer + 51) ) = (U16) round(setVal->cam1BoreY*100.0);
    *( (S16*)(tcBuffer + 53) ) = (S16) round(setVal->cam2Angle1*100.0);
    *( (S16*)(tcBuffer + 55) ) = (S16) round(setVal->cam2Angle2*100.0);
    *( (S16*)(tcBuffer + 57) ) = (S16) round(setVal->cam2Angle3*100.0);
    *( (U8*)(tcBuffer + 59) ) = setVal->cam2Threshold;
    *( (U16*)(tcBuffer + 61) ) = setVal->cam2Exposure;
    *( (U16*)(tcBuffer + 63) ) = (U16) round(setVal->cam2BoreX*100.0);
    *( (U16*)(tcBuffer + 65) ) = (U16) round(setVal->cam2BoreY*100.0);
    *( (U8*)(tcBuffer + 67) ) = setVal->nadirMaxDeviationPercentage;
    *( (U8*)(tcBuffer + 68) ) = setVal->nadirMaxBadEdges;
    *( (U8*)(tcBuffer + 69) ) = setVal->nadirMaxRadius;
    *( (U8*)(tcBuffer + 70) ) = setVal->nadirMinRadius;
    *( (U16*)(tcBuffer + 71) ) = setVal->cam1MaskArea1Xmin;
    *( (U16*)(tcBuffer + 73) ) = setVal->cam1MaskArea1Xmax;
    *( (U16*)(tcBuffer + 75) ) = setVal->cam1MaskArea1Ymin;
    *( (U16*)(tcBuffer + 77) ) = setVal->cam1MaskArea1Ymax;
    *( (U16*)(tcBuffer + 79) ) = setVal->cam1MaskArea2Xmin;
    *( (U16*)(tcBuffer + 81) ) = setVal->cam1MaskArea2Xmax;
    *( (U16*)(tcBuffer + 83) ) = setVal->cam1MaskArea2Ymin;
    *( (U16*)(tcBuffer + 85) ) = setVal->cam1MaskArea2Ymax;
    *( (U16*)(tcBuffer + 87) ) = setVal->cam1MaskArea3Xmin;
    *( (U16*)(tcBuffer + 89) ) = setVal->cam1MaskArea3Xmax;
    *( (U16*)(tcBuffer + 91) ) = setVal->cam1MaskArea3Ymin;
    *( (U16*)(tcBuffer + 93) ) = setVal->cam1MaskArea3Ymax;
    *( (U16*)(tcBuffer + 95) ) = setVal->cam1MaskArea4Xmin;
    *( (U16*)(tcBuffer + 97) ) = setVal->cam1MaskArea4Xmax;
    *( (U16*)(tcBuffer + 99) ) = setVal->cam1MaskArea4Ymin;
    *( (U16*)(tcBuffer + 101) ) = setVal->cam1MaskArea4Ymax;
    *( (U16*)(tcBuffer + 103) ) = setVal->cam1MaskArea5Xmin;
    *( (U16*)(tcBuffer + 105) ) = setVal->cam1MaskArea5Xmax;
    *( (U16*)(tcBuffer + 107) ) = setVal->cam1MaskArea5Ymin;
    *( (U16*)(tcBuffer + 109) ) = setVal->cam1MaskArea5Ymax;
    *( (U16*)(tcBuffer + 111) ) = setVal->cam2MaskArea1Xmin;
    *( (U16*)(tcBuffer + 113) ) = setVal->cam2MaskArea1Xmax;
    *( (U16*)(tcBuffer + 115) ) = setVal->cam2MaskArea1Ymin;
    *( (U16*)(tcBuffer + 117) ) = setVal->cam2MaskArea1Ymax;
    *( (U16*)(tcBuffer + 119) ) = setVal->cam2MaskArea2Xmin;
    *( (U16*)(tcBuffer + 121) ) = setVal->cam2MaskArea2Xmax;
    *( (U16*)(tcBuffer + 123) ) = setVal->cam2MaskArea2Ymin;
    *( (U16*)(tcBuffer + 125) ) = setVal->cam2MaskArea2Ymax;
    *( (U16*)(tcBuffer + 127) ) = setVal->cam2MaskArea3Xmin;
    *( (U16*)(tcBuffer + 129) ) = setVal->cam2MaskArea3Xmax;
    *( (U16*)(tcBuffer + 131) ) = setVal->cam2MaskArea3Ymin;
    *( (U16*)(tcBuffer + 133) ) = setVal->cam2MaskArea3Ymax;
    *( (U16*)(tcBuffer + 135) ) = setVal->cam2MaskArea4Xmin;
    *( (U16*)(tcBuffer + 137) ) = setVal->cam2MaskArea4Xmax;
    *( (U16*)(tcBuffer + 139) ) = setVal->cam2MaskArea4Ymin;
    *( (U16*)(tcBuffer + 141) ) = setVal->cam2MaskArea4Ymax;
    *( (U16*)(tcBuffer + 143) ) = setVal->cam2MaskArea5Xmin;
    *( (U16*)(tcBuffer + 145) ) = setVal->cam2MaskArea5Xmax;
    *( (U16*)(tcBuffer + 147) ) = setVal->cam2MaskArea5Ymin;
    *( (U16*)(tcBuffer + 149) ) = setVal->cam2MaskArea5Ymax;
    *( (S16*)(tcBuffer + 151) ) = (S16) round(setVal->magmAngle1*100.0);
    *( (S16*)(tcBuffer + 153) ) = (S16) round(setVal->magmAngle2*100.0);
    *( (S16*)(tcBuffer + 155) ) = (S16) round(setVal->magmAngle3*100.0);
    *( (S16*)(tcBuffer + 157) ) = (S16) round(setVal->magmOffset1*1000.0);
    *( (S16*)(tcBuffer + 159) ) = (S16) round(setVal->magmOffset2*1000.0);
    *( (S16*)(tcBuffer + 161) ) = (S16) round(setVal->magmOffset3*1000.0);
    *( (S16*)(tcBuffer + 163) ) = (S16) round(setVal->magmSens11*1000.0);
    *( (S16*)(tcBuffer + 165) ) = (S16) round(setVal->magmSens22*1000.0);
    *( (S16*)(tcBuffer + 167) ) = (S16) round(setVal->magmSens33*1000.0);
    *( (S16*)(tcBuffer + 169) ) = (S16) round(setVal->magmSens12*1000.0);
    *( (S16*)(tcBuffer + 171) ) = (S16) round(setVal->magmSens13*1000.0);
    *( (S16*)(tcBuffer + 173) ) = (S16) round(setVal->magmSens21*1000.0);
    *( (S16*)(tcBuffer + 175) ) = (S16) round(setVal->magmSens23*1000.0);
    *( (S16*)(tcBuffer + 177) ) = (S16) round(setVal->magmSens31*1000.0);
    *( (S16*)(tcBuffer + 179) ) = (S16) round(setVal->magmSens32*1000.0);
    *( (S16*)(tcBuffer + 181) ) = (S16) round(setVal->mredAngle1*100.0);
    *( (S16*)(tcBuffer + 183) ) = (S16) round(setVal->mredAngle2*100.0);
    *( (S16*)(tcBuffer + 185) ) = (S16) round(setVal->mredAngle3*100.0);
    *( (S16*)(tcBuffer + 187) ) = (S16) round(setVal->mredOffset1*1000.0);
    *( (S16*)(tcBuffer + 189) ) = (S16) round(setVal->mredOffset2*1000.0);
    *( (S16*)(tcBuffer + 191) ) = (S16) round(setVal->mredOffset3*1000.0);
    *( (S16*)(tcBuffer + 193) ) = (S16) round(setVal->mredSens11*1000.0);
    *( (S16*)(tcBuffer + 195) ) = (S16) round(setVal->mredSens22*1000.0);
    *( (S16*)(tcBuffer + 197) ) = (S16) round(setVal->mredSens33*1000.0);
    *( (S16*)(tcBuffer + 199) ) = (S16) round(setVal->mredSens12*1000.0);
    *( (S16*)(tcBuffer + 201) ) = (S16) round(setVal->mredSens13*1000.0);
    *( (S16*)(tcBuffer + 203) ) = (S16) round(setVal->mredSens21*1000.0);
    *( (S16*)(tcBuffer + 205) ) = (S16) round(setVal->mredSens23*1000.0);
    *( (S16*)(tcBuffer + 207) ) = (S16) round(setVal->mredSens31*1000.0);
    *( (S16*)(tcBuffer + 209) ) = (S16) round(setVal->mredSens32*1000.0);
    *( (S16*)(tcBuffer + 211) ) = (S16) round(setVal->starAngle1*100.0);
    *( (S16*)(tcBuffer + 213) ) = (S16) round(setVal->starAngle2*100.0);
    *( (S16*)(tcBuffer + 215) ) = (S16) round(setVal->starAngle3*100.0);
    *( (U16*)(tcBuffer + 217) ) = setVal->starExposure;
    *( (U16*)(tcBuffer + 219) ) = setVal->starGain;
    *( (U8*)(tcBuffer + 221) ) = setVal->detectionThreshold;
    *( (U8*)(tcBuffer + 222) ) = setVal->starThreshold;
    *( (U8*)(tcBuffer + 223) ) = setVal->maxStarMatched;
    *( (U16*)(tcBuffer + 224) ) = setVal->starTimeoutTime;
    *( (U8*)(tcBuffer + 226) ) = setVal->maxStarPixel;
    *( (U8*)(tcBuffer + 227) ) = setVal->minStarPixel;
    *( (U8*)(tcBuffer + 228) ) = (U8) round(setVal->starErrorMargin*100.0);
    *( (U16*)(tcBuffer + 229) ) = setVal->starDelayTime;
    *( (F32*)(tcBuffer + 231) ) = setVal->starCentX;
    *( (F32*)(tcBuffer + 235) ) = setVal->starCentY;
    *( (F32*)(tcBuffer + 239) ) = setVal->starFocal;
    *( (F32*)(tcBuffer + 243) ) = setVal->starLensK1;
    *( (F32*)(tcBuffer + 247) ) = setVal->starLensK2;
    *( (F32*)(tcBuffer + 251) ) = setVal->starLensP1;
    *( (F32*)(tcBuffer + 255) ) = setVal->starLensP2;
    *( (U8*)(tcBuffer + 259) ) = setVal->starWindowWidth;
    *( (U8*)(tcBuffer + 260) ) = (U8) round(setVal->starTrackingMargin*100.0);
    *( (U8*)(tcBuffer + 261) ) = (U8) round(setVal->starValidationMargin*100.0);
    *( (U8*)(tcBuffer + 263) ) = (U8) round(setVal->starSearchWidth*5.0);
    *( (F32*)(tcBuffer + 264) ) = setVal->ks;
    *( (F32*)(tcBuffer + 268) ) = setVal->kd;
    *( (S16*)(tcBuffer + 272) ) = (S16) round(setVal->wy_ref*1000.0);
    *( (F32*)(tcBuffer + 274) ) = setVal->kdf;
    *( (F32*)(tcBuffer + 278) ) = setVal->kh;
    *( (F32*)(tcBuffer + 282) ) = setVal->kn;
    *( (F32*)(tcBuffer + 286) ) = setVal->kp1;
    *( (F32*)(tcBuffer + 290) ) = setVal->kd1;
    *( (F32*)(tcBuffer + 294) ) = setVal->h_ref;
    *( (F32*)(tcBuffer + 298) ) = setVal->kp2;
    *( (F32*)(tcBuffer + 302) ) = setVal->kd2;
    *( (F32*)(tcBuffer + 306) ) = setVal->h_bias;
    *( (F32*)(tcBuffer + 311) ) = setVal->kp3;
    *( (F32*)(tcBuffer + 315) ) = setVal->kd3;
    *( (F32*)(tcBuffer + 319) ) = setVal->ki3;
    *( (F32*)(tcBuffer + 324) ) = setVal->ixx;
    *( (F32*)(tcBuffer + 328) ) = setVal->iyy;
    *( (F32*)(tcBuffer + 332) ) = setVal->izz;
    *( (F32*)(tcBuffer + 336) ) = setVal->ixy;
    *( (F32*)(tcBuffer + 340) ) = setVal->ixz;
    *( (F32*)(tcBuffer + 344) ) = setVal->iyz;
    *( (F32*)(tcBuffer + 348) ) = setVal->magRateNoise;
    *( (F32*)(tcBuffer + 352) ) = setVal->ekfSysNoise;
    *( (F32*)(tcBuffer + 356) ) = setVal->cssNoise;
    *( (F32*)(tcBuffer + 360) ) = setVal->sunNoise;
    *( (F32*)(tcBuffer + 364) ) = setVal->nadirNoise;
    *( (F32*)(tcBuffer + 368) ) = setVal->magNoise;
    *( (F32*)(tcBuffer + 372) ) = setVal->starNoise;
    *( (U8*)(tcBuffer + 378) ) = setVal->cam1Cam2Period;
    *( (U16*)(tcBuffer + 379) ) = (U16) round(setVal->aInclCoeff*1000.0);
    *( (U16*)(tcBuffer + 381) ) = (U16) round(setVal->aRaanCoeff*1000.0);
    *( (U16*)(tcBuffer + 383) ) = (U16) round(setVal->aEccCoeff*1000.0);
    *( (U16*)(tcBuffer + 385) ) = (U16) round(setVal->aArgPerCoeff*1000.0);
    *( (U16*)(tcBuffer + 387) ) = (U16) round(setVal->aTimeCoeff*1000.0);
    *( (U16*)(tcBuffer + 389) ) = (U16) round(setVal->aPosCoeff*1000.0);
    *( (U8*)(tcBuffer + 391) ) = (U8) round(setVal->asgp4MaxPosError*10.0);
    *( (S32*)(tcBuffer + 393) ) = (S32) round(setVal->asgp4Xp*1E7);
    *( (S32*)(tcBuffer + 397) ) = (S32) round(setVal->asgp4Yp*1E7);
    *( (U8*)(tcBuffer + 401) ) = setVal->asgp4GpsRollover;
    *( (U8*)(tcBuffer + 402) ) = (U8) round(setVal->asgp4PosSdTh*10.0);
    *( (U8*)(tcBuffer + 403) ) = (U8) round(setVal->asgp4VelSdTh*100.0);
    *( (U8*)(tcBuffer + 404) ) = setVal->asgp4MinSat;
    *( (U8*)(tcBuffer + 405) ) = (U8) round(setVal->asgp4TimeGain*100.0);
    *( (U8*)(tcBuffer + 406) ) = (U8) round(setVal->asgp4MaxLag*100.0);
    *( (U16*)(tcBuffer + 407) ) = setVal->asgp4MinSamples;
    memcpy(tcBuffer + 409,setVal->userConSettings,48);
    memcpy(tcBuffer + 457,setVal->userEstSettings,48);

    return 505;
}

uint16_t CUBEACP_FormatAdcsEnabledCmd(uint8_t* tcBuffer, CUBEACP_AdcsRunMode_t enabled)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 10;

    tcBuffer[1] = 
        (enabled << 0);

    return 2;
}

uint16_t CUBEACP_FormatAdcsPowerCmd(uint8_t* tcBuffer, CUBEACP_AdcsPower_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 11;

    tcBuffer[1] = 
        (setVal->cubeControlSignalPower << 0) + 
        (setVal->cubeControlMotorPower << 2) + 
        (setVal->cubeSense1Power << 4) + 
        (setVal->cubeSense2Power << 6);
    tcBuffer[2] = 
        (setVal->cubeStarPower << 0) + 
        (setVal->cubeWheel1Power << 2) + 
        (setVal->cubeWheel2Power << 4) + 
        (setVal->cubeWheel3Power << 6);
    tcBuffer[3] = 
        (setVal->motorPower << 0) + 
        (setVal->gpsLnaPower << 2);

    return 4;
}

uint16_t CUBEACP_FormatAdcsSystemConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsSystemConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 30;

    tcBuffer[1] = 
        (setVal->acpType << 0) + 
        (setVal->specialControl << 4);
    tcBuffer[6] = 
        (setVal->csCam1Type << 0) + 
        (setVal->csCam2Type << 4);
    tcBuffer[8] = 
        (setVal->gpsType << 0) + 
        (setVal->hasRedMag << 4);
    tcBuffer[165] = 
        (setVal->ccsEnablePort << 0) + 
        (setVal->ccsEnablePin << 4);
    tcBuffer[166] = 
        (setVal->ccmEnablePort << 0) + 
        (setVal->ccmEnablePin << 4);
    tcBuffer[167] = 
        (setVal->cccEnablePort << 0) + 
        (setVal->cccEnablePin << 4);
    tcBuffer[168] = 
        (setVal->cSense1EnablePort << 0) + 
        (setVal->cSense1EnablePin << 4);
    tcBuffer[169] = 
        (setVal->cSense2EnablePort << 0) + 
        (setVal->cSense2EnablePin << 4);
    tcBuffer[170] = 
        (setVal->cStarEnablePort << 0) + 
        (setVal->cStarEnablePin << 4);
    tcBuffer[171] = 
        (setVal->cW1EnablePort << 0) + 
        (setVal->cW1EnablePin << 4);
    tcBuffer[172] = 
        (setVal->cW2EnablePort << 0) + 
        (setVal->cW2EnablePin << 4);
    tcBuffer[173] = 
        (setVal->cW3EnablePort << 0) + 
        (setVal->cW3EnablePin << 4);
    *( (U8*)(tcBuffer + 2) ) = setVal->ccSignalVer;
    *( (U8*)(tcBuffer + 3) ) = setVal->ccMotorVer;
    *( (U8*)(tcBuffer + 4) ) = setVal->cs1Ver;
    *( (U8*)(tcBuffer + 5) ) = setVal->cs2Ver;
    *( (U8*)(tcBuffer + 7) ) = setVal->cubeStarVer;
    *( (F32*)(tcBuffer + 9) ) = setVal->mqx;
    *( (F32*)(tcBuffer + 13) ) = setVal->mqy;
    *( (F32*)(tcBuffer + 17) ) = setVal->mqz;
    *( (F32*)(tcBuffer + 21) ) = setVal->mtTmin;
    *( (F32*)(tcBuffer + 25) ) = setVal->mtTmax;
    *( (F32*)(tcBuffer + 29) ) = setVal->nSatX;
    *( (F32*)(tcBuffer + 33) ) = setVal->nSatY;
    *( (F32*)(tcBuffer + 37) ) = setVal->nSatZ;
    *( (F32*)(tcBuffer + 41) ) = setVal->hSatX;
    *( (F32*)(tcBuffer + 45) ) = setVal->hSatY;
    *( (F32*)(tcBuffer + 49) ) = setVal->hSatZ;
    *( (F32*)(tcBuffer + 53) ) = setVal->iwx;
    *( (F32*)(tcBuffer + 57) ) = setVal->iwy;
    *( (F32*)(tcBuffer + 61) ) = setVal->iwz;
    *( (F32*)(tcBuffer + 65) ) = setVal->ndel;
    *( (F32*)(tcBuffer + 69) ) = setVal->biasX_d1;
    *( (F32*)(tcBuffer + 73) ) = setVal->biasY_d1;
    *( (F32*)(tcBuffer + 77) ) = setVal->biasZ_d1;
    *( (F32*)(tcBuffer + 81) ) = setVal->biasX_d2;
    *( (F32*)(tcBuffer + 85) ) = setVal->biasY_d2;
    *( (F32*)(tcBuffer + 89) ) = setVal->biasZ_d2;
    *( (F32*)(tcBuffer + 93) ) = setVal->sensX_s1;
    *( (F32*)(tcBuffer + 97) ) = setVal->sensY_s1;
    *( (F32*)(tcBuffer + 101) ) = setVal->sensZ_s1;
    *( (F32*)(tcBuffer + 105) ) = setVal->sensX_s2;
    *( (F32*)(tcBuffer + 109) ) = setVal->sensY_s2;
    *( (F32*)(tcBuffer + 113) ) = setVal->sensZ_s2;
    *( (F32*)(tcBuffer + 117) ) = setVal->red_BiasX_d1;
    *( (F32*)(tcBuffer + 121) ) = setVal->red_BiasY_d1;
    *( (F32*)(tcBuffer + 125) ) = setVal->red_BiasZ_d1;
    *( (F32*)(tcBuffer + 129) ) = setVal->red_BiasX_d2;
    *( (F32*)(tcBuffer + 133) ) = setVal->red_BiasY_d2;
    *( (F32*)(tcBuffer + 137) ) = setVal->red_BiasZ_d2;
    *( (F32*)(tcBuffer + 141) ) = setVal->red_SensX_s1;
    *( (F32*)(tcBuffer + 145) ) = setVal->red_SensY_s1;
    *( (F32*)(tcBuffer + 149) ) = setVal->red_SensZ_s1;
    *( (F32*)(tcBuffer + 153) ) = setVal->red_SensX_s2;
    *( (F32*)(tcBuffer + 157) ) = setVal->red_SensY_s2;
    *( (F32*)(tcBuffer + 161) ) = setVal->red_SensZ_s2;

    return 174;
}

uint16_t CUBEACP_FormatAsgp4ModeCmd(uint8_t* tcBuffer, CUBEACP_Asgp4ModeSelect_t asgp4ModeSelection)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 31;

    tcBuffer[1] = 
        (asgp4ModeSelection << 0);

    return 2;
}

uint16_t CUBEACP_FormatASgp4ParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 28;

    *( (U16*)(tcBuffer + 1) ) = (U16) round(setVal->aInclCoeff*1000.0);
    *( (U16*)(tcBuffer + 3) ) = (U16) round(setVal->aRaanCoeff*1000.0);
    *( (U16*)(tcBuffer + 5) ) = (U16) round(setVal->aEccCoeff*1000.0);
    *( (U16*)(tcBuffer + 7) ) = (U16) round(setVal->aArgPerCoeff*1000.0);
    *( (U16*)(tcBuffer + 9) ) = (U16) round(setVal->aTimeCoeff*1000.0);
    *( (U16*)(tcBuffer + 11) ) = (U16) round(setVal->aPosCoeff*1000.0);
    *( (U8*)(tcBuffer + 13) ) = (U8) round(setVal->asgp4MaxPosError*10.0);
    *( (S32*)(tcBuffer + 15) ) = (S32) round(setVal->asgp4Xp*1E7);
    *( (S32*)(tcBuffer + 19) ) = (S32) round(setVal->asgp4Yp*1E7);
    *( (U8*)(tcBuffer + 23) ) = setVal->asgp4GpsRollover;
    *( (U8*)(tcBuffer + 24) ) = (U8) round(setVal->asgp4PosSdTh*10.0);
    *( (U8*)(tcBuffer + 25) ) = (U8) round(setVal->asgp4VelSdTh*100.0);
    *( (U8*)(tcBuffer + 26) ) = setVal->asgp4MinSat;
    *( (U8*)(tcBuffer + 27) ) = (U8) round(setVal->asgp4TimeGain*100.0);
    *( (U8*)(tcBuffer + 28) ) = (U8) round(setVal->asgp4MaxLag*100.0);
    *( (U16*)(tcBuffer + 29) ) = setVal->asgp4MinSamples;

    return 31;
}

uint16_t CUBEACP_FormatAsgp4TriggerCmd(uint8_t* tcBuffer)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 32;


    return 1;
}

uint16_t CUBEACP_FormatClearErrorsCmd(uint8_t* tcBuffer, CUBEACP_ClearErrors_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 12;

    tcBuffer[1] = 
        (setVal->aDCSErrors << 0) + 
        (setVal->hKErrors << 1);

    return 2;
}

uint16_t CUBEACP_FormatCmdAttitudeCmd(uint8_t* tcBuffer, CUBEACP_CmdAttitude_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 15;

    *( (S16*)(tcBuffer + 1) ) = (S16) round(setVal->roll*100.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(setVal->pitch*100.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(setVal->yaw*100.0);

    return 7;
}

uint16_t CUBEACP_FormatCmdTrackingTargetCmd(uint8_t* tcBuffer, F32 longRef, F32 latRef, F32 altRef)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 55;

    *( (F32*)(tcBuffer + 1) ) = longRef;
    *( (F32*)(tcBuffer + 5) ) = latRef;
    *( (F32*)(tcBuffer + 9) ) = altRef;

    return 13;
}

uint16_t CUBEACP_FormatControlModeCmd(uint8_t* tcBuffer, CUBEACP_ControlMode_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 13;

    tcBuffer[1] = 
        (setVal->controlModeSelection << 0);
    *( (U16*)(tcBuffer + 2) ) = setVal->timeout;

    return 4;
}

uint16_t CUBEACP_FormatConvertCmd(uint8_t* tcBuffer, U8 srcFileCtr, U8 qualityFactor, U8 whiteBalance)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 57;

    *( (U8*)(tcBuffer + 1) ) = srcFileCtr;
    *( (U8*)(tcBuffer + 2) ) = qualityFactor;
    *( (U8*)(tcBuffer + 3) ) = whiteBalance;

    return 4;
}

uint16_t CUBEACP_FormatCssConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 24;

    tcBuffer[1] = 
        (setVal->css1Conf << 0);
    tcBuffer[2] = 
        (setVal->css2Conf << 0);
    tcBuffer[3] = 
        (setVal->css3Conf << 0);
    tcBuffer[4] = 
        (setVal->css4Conf << 0);
    *( (U8*)(tcBuffer + 11) ) = (U8) round(setVal->css1Scale*100.0);
    *( (U8*)(tcBuffer + 12) ) = (U8) round(setVal->css2Scale*100.0);
    *( (U8*)(tcBuffer + 13) ) = (U8) round(setVal->css3Scale*100.0);
    *( (U8*)(tcBuffer + 14) ) = (U8) round(setVal->css4Scale*100.0);
    *( (U8*)(tcBuffer + 15) ) = (U8) round(setVal->css5Scale*100.0);
    *( (U8*)(tcBuffer + 16) ) = (U8) round(setVal->css6Scale*100.0);
    *( (U8*)(tcBuffer + 17) ) = (U8) round(setVal->css7Scale*100.0);
    *( (U8*)(tcBuffer + 18) ) = (U8) round(setVal->css8Scale*100.0);
    *( (U8*)(tcBuffer + 19) ) = (U8) round(setVal->css9Scale*100.0);
    *( (U8*)(tcBuffer + 20) ) = (U8) round(setVal->css10Scale*100.0);
    *( (U8*)(tcBuffer + 21) ) = setVal->cssMinimum;

    return 22;
}

uint16_t CUBEACP_FormatCubeSenseConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 25;

    tcBuffer[8] = 
        (setVal->cam1AutoAdj << 0);
    tcBuffer[22] = 
        (setVal->cam2AutoAdj << 0);
    *( (S16*)(tcBuffer + 1) ) = (S16) round(setVal->cam1Angle1*100.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(setVal->cam1Angle2*100.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(setVal->cam1Angle3*100.0);
    *( (U8*)(tcBuffer + 7) ) = setVal->cam1Threshold;
    *( (U16*)(tcBuffer + 9) ) = setVal->cam1Exposure;
    *( (U16*)(tcBuffer + 11) ) = (U16) round(setVal->cam1BoreX*100.0);
    *( (U16*)(tcBuffer + 13) ) = (U16) round(setVal->cam1BoreY*100.0);
    *( (S16*)(tcBuffer + 15) ) = (S16) round(setVal->cam2Angle1*100.0);
    *( (S16*)(tcBuffer + 17) ) = (S16) round(setVal->cam2Angle2*100.0);
    *( (S16*)(tcBuffer + 19) ) = (S16) round(setVal->cam2Angle3*100.0);
    *( (U8*)(tcBuffer + 21) ) = setVal->cam2Threshold;
    *( (U16*)(tcBuffer + 23) ) = setVal->cam2Exposure;
    *( (U16*)(tcBuffer + 25) ) = (U16) round(setVal->cam2BoreX*100.0);
    *( (U16*)(tcBuffer + 27) ) = (U16) round(setVal->cam2BoreY*100.0);
    *( (U8*)(tcBuffer + 29) ) = setVal->nadirMaxDeviationPercentage;
    *( (U8*)(tcBuffer + 30) ) = setVal->nadirMaxBadEdges;
    *( (U8*)(tcBuffer + 31) ) = setVal->nadirMaxRadius;
    *( (U8*)(tcBuffer + 32) ) = setVal->nadirMinRadius;
    *( (U16*)(tcBuffer + 33) ) = setVal->cam1MaskArea1Xmin;
    *( (U16*)(tcBuffer + 35) ) = setVal->cam1MaskArea1Xmax;
    *( (U16*)(tcBuffer + 37) ) = setVal->cam1MaskArea1Ymin;
    *( (U16*)(tcBuffer + 39) ) = setVal->cam1MaskArea1Ymax;
    *( (U16*)(tcBuffer + 41) ) = setVal->cam1MaskArea2Xmin;
    *( (U16*)(tcBuffer + 43) ) = setVal->cam1MaskArea2Xmax;
    *( (U16*)(tcBuffer + 45) ) = setVal->cam1MaskArea2Ymin;
    *( (U16*)(tcBuffer + 47) ) = setVal->cam1MaskArea2Ymax;
    *( (U16*)(tcBuffer + 49) ) = setVal->cam1MaskArea3Xmin;
    *( (U16*)(tcBuffer + 51) ) = setVal->cam1MaskArea3Xmax;
    *( (U16*)(tcBuffer + 53) ) = setVal->cam1MaskArea3Ymin;
    *( (U16*)(tcBuffer + 55) ) = setVal->cam1MaskArea3Ymax;
    *( (U16*)(tcBuffer + 57) ) = setVal->cam1MaskArea4Xmin;
    *( (U16*)(tcBuffer + 59) ) = setVal->cam1MaskArea4Xmax;
    *( (U16*)(tcBuffer + 61) ) = setVal->cam1MaskArea4Ymin;
    *( (U16*)(tcBuffer + 63) ) = setVal->cam1MaskArea4Ymax;
    *( (U16*)(tcBuffer + 65) ) = setVal->cam1MaskArea5Xmin;
    *( (U16*)(tcBuffer + 67) ) = setVal->cam1MaskArea5Xmax;
    *( (U16*)(tcBuffer + 69) ) = setVal->cam1MaskArea5Ymin;
    *( (U16*)(tcBuffer + 71) ) = setVal->cam1MaskArea5Ymax;
    *( (U16*)(tcBuffer + 73) ) = setVal->cam2MaskArea1Xmin;
    *( (U16*)(tcBuffer + 75) ) = setVal->cam2MaskArea1Xmax;
    *( (U16*)(tcBuffer + 77) ) = setVal->cam2MaskArea1Ymin;
    *( (U16*)(tcBuffer + 79) ) = setVal->cam2MaskArea1Ymax;
    *( (U16*)(tcBuffer + 81) ) = setVal->cam2MaskArea2Xmin;
    *( (U16*)(tcBuffer + 83) ) = setVal->cam2MaskArea2Xmax;
    *( (U16*)(tcBuffer + 85) ) = setVal->cam2MaskArea2Ymin;
    *( (U16*)(tcBuffer + 87) ) = setVal->cam2MaskArea2Ymax;
    *( (U16*)(tcBuffer + 89) ) = setVal->cam2MaskArea3Xmin;
    *( (U16*)(tcBuffer + 91) ) = setVal->cam2MaskArea3Xmax;
    *( (U16*)(tcBuffer + 93) ) = setVal->cam2MaskArea3Ymin;
    *( (U16*)(tcBuffer + 95) ) = setVal->cam2MaskArea3Ymax;
    *( (U16*)(tcBuffer + 97) ) = setVal->cam2MaskArea4Xmin;
    *( (U16*)(tcBuffer + 99) ) = setVal->cam2MaskArea4Xmax;
    *( (U16*)(tcBuffer + 101) ) = setVal->cam2MaskArea4Ymin;
    *( (U16*)(tcBuffer + 103) ) = setVal->cam2MaskArea4Ymax;
    *( (U16*)(tcBuffer + 105) ) = setVal->cam2MaskArea5Xmin;
    *( (U16*)(tcBuffer + 107) ) = setVal->cam2MaskArea5Xmax;
    *( (U16*)(tcBuffer + 109) ) = setVal->cam2MaskArea5Ymin;
    *( (U16*)(tcBuffer + 111) ) = setVal->cam2MaskArea5Ymax;

    return 113;
}

uint16_t CUBEACP_FormatDeployMagnetometerCmd(uint8_t* tcBuffer, U8 timeout)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 7;

    *( (U8*)(tcBuffer + 1) ) = timeout;

    return 2;
}

uint16_t CUBEACP_FormatDetumbleParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 38;

    *( (F32*)(tcBuffer + 1) ) = setVal->ks;
    *( (F32*)(tcBuffer + 5) ) = setVal->kd;
    *( (S16*)(tcBuffer + 9) ) = (S16) round(setVal->wy_ref*1000.0);
    *( (F32*)(tcBuffer + 11) ) = setVal->kdf;

    return 15;
}

uint16_t CUBEACP_FormatEstimModeCmd(uint8_t* tcBuffer, CUBEACP_EstimModeSelect_t estimModeSelection)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 14;

    tcBuffer[1] = 
        (estimModeSelection << 0);

    return 2;
}

uint16_t CUBEACP_FormatEstimParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 27;

    *( (F32*)(tcBuffer + 1) ) = setVal->magRateNoise;
    *( (F32*)(tcBuffer + 5) ) = setVal->ekfSysNoise;
    *( (F32*)(tcBuffer + 9) ) = setVal->cssNoise;
    *( (F32*)(tcBuffer + 13) ) = setVal->sunNoise;
    *( (F32*)(tcBuffer + 17) ) = setVal->nadirNoise;
    *( (F32*)(tcBuffer + 21) ) = setVal->magNoise;
    *( (F32*)(tcBuffer + 25) ) = setVal->starNoise;
    *( (U8*)(tcBuffer + 31) ) = setVal->cam1Cam2Period;

    return 32;
}

uint16_t CUBEACP_FormatGyroConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 23;

    tcBuffer[1] = 
        (setVal->gyro1Conf << 0);
    tcBuffer[2] = 
        (setVal->gyro2Conf << 0);
    tcBuffer[3] = 
        (setVal->gyro3Conf << 0);
    *( (S16*)(tcBuffer + 4) ) = (S16) round(setVal->xRateOffset*1000.0);
    *( (S16*)(tcBuffer + 6) ) = (S16) round(setVal->yRateOffset*1000.0);
    *( (S16*)(tcBuffer + 8) ) = (S16) round(setVal->zRateOffset*1000.0);
    *( (U8*)(tcBuffer + 10) ) = setVal->rateSensorMult;

    return 11;
}

uint16_t CUBEACP_FormatInertialPointReferenceCmd(uint8_t* tcBuffer, F64 inertialRefX, F64 inertialRefY, F64 inertialRefZ)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 34;

    *( (S16*)(tcBuffer + 1) ) = (S16) round(inertialRefX*10000.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(inertialRefY*10000.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(inertialRefZ*10000.0);

    return 7;
}

uint16_t CUBEACP_FormatLogSdConfig1Cmd(uint8_t* tcBuffer, U8* logSelection, U16 period, CUBEACP_SdLogSelect_t destination)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 104;

    tcBuffer[13] = 
        (destination << 0);
    memcpy(tcBuffer + 1,logSelection,10);
    *( (U16*)(tcBuffer + 11) ) = period;

    return 14;
}

uint16_t CUBEACP_FormatLogSdConfig2Cmd(uint8_t* tcBuffer, U8* logSelection, U16 period, CUBEACP_SdLogSelect_t destination)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 105;

    tcBuffer[13] = 
        (destination << 0);
    memcpy(tcBuffer + 1,logSelection,10);
    *( (U16*)(tcBuffer + 11) ) = period;

    return 14;
}

uint16_t CUBEACP_FormatLogUartConfigCmd(uint8_t* tcBuffer, U8* selection, U16 period)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 106;

    memcpy(tcBuffer + 1,selection,10);
    *( (U16*)(tcBuffer + 11) ) = period;

    return 13;
}

uint16_t CUBEACP_FormatMagConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 26;

    *( (S16*)(tcBuffer + 1) ) = (S16) round(setVal->magmAngle1*100.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(setVal->magmAngle2*100.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(setVal->magmAngle3*100.0);
    *( (S16*)(tcBuffer + 7) ) = (S16) round(setVal->magmOffset1*1000.0);
    *( (S16*)(tcBuffer + 9) ) = (S16) round(setVal->magmOffset2*1000.0);
    *( (S16*)(tcBuffer + 11) ) = (S16) round(setVal->magmOffset3*1000.0);
    *( (S16*)(tcBuffer + 13) ) = (S16) round(setVal->magmSens11*1000.0);
    *( (S16*)(tcBuffer + 15) ) = (S16) round(setVal->magmSens22*1000.0);
    *( (S16*)(tcBuffer + 17) ) = (S16) round(setVal->magmSens33*1000.0);
    *( (S16*)(tcBuffer + 19) ) = (S16) round(setVal->magmSens12*1000.0);
    *( (S16*)(tcBuffer + 21) ) = (S16) round(setVal->magmSens13*1000.0);
    *( (S16*)(tcBuffer + 23) ) = (S16) round(setVal->magmSens21*1000.0);
    *( (S16*)(tcBuffer + 25) ) = (S16) round(setVal->magmSens23*1000.0);
    *( (S16*)(tcBuffer + 27) ) = (S16) round(setVal->magmSens31*1000.0);
    *( (S16*)(tcBuffer + 29) ) = (S16) round(setVal->magmSens32*1000.0);

    return 31;
}

uint16_t CUBEACP_FormatMagModeCmd(uint8_t* tcBuffer, CUBEACP_MagModeVal_t modeSetting)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 56;

    tcBuffer[1] = 
        (modeSetting << 0);

    return 2;
}

uint16_t CUBEACP_FormatMagtorqConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 21;

    tcBuffer[1] = 
        (setVal->magtorq1 << 0);
    tcBuffer[2] = 
        (setVal->magtorq2 << 0);
    tcBuffer[3] = 
        (setVal->magtorq3 << 0);

    return 4;
}

uint16_t CUBEACP_FormatMoICmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 41;

    *( (F32*)(tcBuffer + 1) ) = setVal->ixx;
    *( (F32*)(tcBuffer + 5) ) = setVal->iyy;
    *( (F32*)(tcBuffer + 9) ) = setVal->izz;
    *( (F32*)(tcBuffer + 13) ) = setVal->ixy;
    *( (F32*)(tcBuffer + 17) ) = setVal->ixz;
    *( (F32*)(tcBuffer + 21) ) = setVal->iyz;

    return 25;
}

uint16_t CUBEACP_FormatOrbitArgPerCmd(uint8_t* tcBuffer, F64 argPerigee)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 49;

    memcpy(tcBuffer + 1, &argPerigee, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitBStarCmd(uint8_t* tcBuffer, F64 bstar)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 50;

    memcpy(tcBuffer + 1, &bstar, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitEccentricityCmd(uint8_t* tcBuffer, F64 eccentricity)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 47;

    memcpy(tcBuffer + 1, &eccentricity, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitEpochCmd(uint8_t* tcBuffer, F64 epoch)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 53;

    memcpy(tcBuffer + 1, &epoch, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitInclinationCmd(uint8_t* tcBuffer, F64 inclination)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 46;

    memcpy(tcBuffer + 1, &inclination, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitMeanAnomCmd(uint8_t* tcBuffer, F64 meanAnomaly)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 52;

    memcpy(tcBuffer + 1, &meanAnomaly, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitMeanMotCmd(uint8_t* tcBuffer, F64 meanMotion)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 51;

    memcpy(tcBuffer + 1, &meanMotion, 8);

    return 9;
}

uint16_t CUBEACP_FormatOrbitParametersCmd(uint8_t* tcBuffer, CUBEACP_OrbitParameters_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 45;

    memcpy(tcBuffer + 1, &setVal->inclination, 8);
    memcpy(tcBuffer + 9, &setVal->eccentricity, 8);
    memcpy(tcBuffer + 17, &setVal->raan, 8);
    memcpy(tcBuffer + 25, &setVal->argPerigee, 8);
    memcpy(tcBuffer + 33, &setVal->bstar, 8);
    memcpy(tcBuffer + 41, &setVal->meanMotion, 8);
    memcpy(tcBuffer + 49, &setVal->meanAnomaly, 8);
    memcpy(tcBuffer + 57, &setVal->epoch, 8);

    return 65;
}

uint16_t CUBEACP_FormatOrbitRaanCmd(uint8_t* tcBuffer, F64 raan)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 48;

    memcpy(tcBuffer + 1, &raan, 8);

    return 9;
}

uint16_t CUBEACP_FormatRedMagConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 36;

    *( (S16*)(tcBuffer + 1) ) = (S16) round(setVal->mredAngle1*100.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(setVal->mredAngle2*100.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(setVal->mredAngle3*100.0);
    *( (S16*)(tcBuffer + 7) ) = (S16) round(setVal->mredOffset1*1000.0);
    *( (S16*)(tcBuffer + 9) ) = (S16) round(setVal->mredOffset2*1000.0);
    *( (S16*)(tcBuffer + 11) ) = (S16) round(setVal->mredOffset3*1000.0);
    *( (S16*)(tcBuffer + 13) ) = (S16) round(setVal->mredSens11*1000.0);
    *( (S16*)(tcBuffer + 15) ) = (S16) round(setVal->mredSens22*1000.0);
    *( (S16*)(tcBuffer + 17) ) = (S16) round(setVal->mredSens33*1000.0);
    *( (S16*)(tcBuffer + 19) ) = (S16) round(setVal->mredSens12*1000.0);
    *( (S16*)(tcBuffer + 21) ) = (S16) round(setVal->mredSens13*1000.0);
    *( (S16*)(tcBuffer + 23) ) = (S16) round(setVal->mredSens21*1000.0);
    *( (S16*)(tcBuffer + 25) ) = (S16) round(setVal->mredSens23*1000.0);
    *( (S16*)(tcBuffer + 27) ) = (S16) round(setVal->mredSens31*1000.0);
    *( (S16*)(tcBuffer + 29) ) = (S16) round(setVal->mredSens32*1000.0);

    return 31;
}

uint16_t CUBEACP_FormatRWheelParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 40;

    *( (F32*)(tcBuffer + 1) ) = setVal->kp2;
    *( (F32*)(tcBuffer + 5) ) = setVal->kd2;
    *( (F32*)(tcBuffer + 9) ) = setVal->h_bias;

    return 14;
}

uint16_t CUBEACP_FormatSaveConfigCmd(uint8_t* tcBuffer)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 63;


    return 1;
}

uint16_t CUBEACP_FormatSaveImageCmd(uint8_t* tcBuffer, CUBEACP_SaveImage_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 80;

    tcBuffer[1] = 
        (setVal->cameraSelect << 0);
    tcBuffer[2] = 
        (setVal->imageSize << 0);

    return 3;
}

uint16_t CUBEACP_FormatSaveOrbitParamsCmd(uint8_t* tcBuffer)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 64;


    return 1;
}

uint16_t CUBEACP_FormatStarConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 37;

    *( (S16*)(tcBuffer + 1) ) = (S16) round(setVal->starAngle1*100.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(setVal->starAngle2*100.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(setVal->starAngle3*100.0);
    *( (U16*)(tcBuffer + 7) ) = setVal->starExposure;
    *( (U16*)(tcBuffer + 9) ) = setVal->starGain;
    *( (U8*)(tcBuffer + 11) ) = setVal->detectionThreshold;
    *( (U8*)(tcBuffer + 12) ) = setVal->starThreshold;
    *( (U8*)(tcBuffer + 13) ) = setVal->maxStarMatched;
    *( (U16*)(tcBuffer + 14) ) = setVal->starTimeoutTime;
    *( (U8*)(tcBuffer + 16) ) = setVal->maxStarPixel;
    *( (U8*)(tcBuffer + 17) ) = setVal->minStarPixel;
    *( (U8*)(tcBuffer + 18) ) = (U8) round(setVal->starErrorMargin*100.0);
    *( (U16*)(tcBuffer + 19) ) = setVal->starDelayTime;
    *( (F32*)(tcBuffer + 21) ) = setVal->starCentX;
    *( (F32*)(tcBuffer + 25) ) = setVal->starCentY;
    *( (F32*)(tcBuffer + 29) ) = setVal->starFocal;
    *( (F32*)(tcBuffer + 33) ) = setVal->starLensK1;
    *( (F32*)(tcBuffer + 37) ) = setVal->starLensK2;
    *( (F32*)(tcBuffer + 41) ) = setVal->starLensP1;
    *( (F32*)(tcBuffer + 45) ) = setVal->starLensP2;
    *( (U8*)(tcBuffer + 49) ) = setVal->starWindowWidth;
    *( (U8*)(tcBuffer + 50) ) = (U8) round(setVal->starTrackingMargin*100.0);
    *( (U8*)(tcBuffer + 51) ) = (U8) round(setVal->starValidationMargin*100.0);
    *( (U8*)(tcBuffer + 53) ) = (U8) round(setVal->starSearchWidth*5.0);

    return 54;
}

uint16_t CUBEACP_FormatTorquerCmdCmd(uint8_t* tcBuffer, CUBEACP_TorquerCmd_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 16;

    *( (S16*)(tcBuffer + 1) ) = (S16) round(setVal->torquerX*1000.0);
    *( (S16*)(tcBuffer + 3) ) = (S16) round(setVal->torquerY*1000.0);
    *( (S16*)(tcBuffer + 5) ) = (S16) round(setVal->torquerZ*1000.0);

    return 7;
}

uint16_t CUBEACP_FormatTrackingParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 54;

    *( (F32*)(tcBuffer + 1) ) = setVal->kp3;
    *( (F32*)(tcBuffer + 5) ) = setVal->kd3;
    *( (F32*)(tcBuffer + 9) ) = setVal->ki3;

    return 14;
}

uint16_t CUBEACP_FormatTriggerAdcsCmd(uint8_t* tcBuffer)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 18;


    return 1;
}

uint16_t CUBEACP_FormatTriggerAdcsSensorCmd(uint8_t* tcBuffer, CUBEACP_TriggerAdcsSensor_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 19;

    tcBuffer[97] = 
        (setVal->gpsSolutionStatus << 0);
    *( (U32*)(tcBuffer + 1) ) = setVal->unixTime;
    *( (U16*)(tcBuffer + 5) ) = setVal->cssRaw1;
    *( (U16*)(tcBuffer + 7) ) = setVal->cssRaw2;
    *( (U16*)(tcBuffer + 9) ) = setVal->cssRaw3;
    *( (U16*)(tcBuffer + 11) ) = setVal->cssRaw4;
    *( (U16*)(tcBuffer + 13) ) = setVal->cssRaw5;
    *( (U16*)(tcBuffer + 15) ) = setVal->cssRaw6;
    *( (U16*)(tcBuffer + 17) ) = setVal->cssRaw7;
    *( (U16*)(tcBuffer + 19) ) = setVal->cssRaw8;
    *( (U16*)(tcBuffer + 21) ) = setVal->cssRaw9;
    *( (U16*)(tcBuffer + 23) ) = setVal->cssRaw10;
    *( (S16*)(tcBuffer + 25) ) = setVal->cam1RawX;
    *( (S16*)(tcBuffer + 27) ) = setVal->cam1RawY;
    *( (U8*)(tcBuffer + 29) ) = setVal->cam1Busy;
    *( (U8*)(tcBuffer + 30) ) = setVal->cam1Result;
    *( (S16*)(tcBuffer + 31) ) = setVal->cam2RawX;
    *( (S16*)(tcBuffer + 33) ) = setVal->cam2RawY;
    *( (U8*)(tcBuffer + 35) ) = setVal->cam2Busy;
    *( (U8*)(tcBuffer + 36) ) = setVal->cam2Result;
    *( (S16*)(tcBuffer + 37) ) = setVal->magRawX;
    *( (S16*)(tcBuffer + 39) ) = setVal->magRawY;
    *( (S16*)(tcBuffer + 41) ) = setVal->magRawZ;
    *( (S32*)(tcBuffer + 43) ) = setVal->rateRawX;
    *( (S32*)(tcBuffer + 47) ) = setVal->rateRawY;
    *( (S32*)(tcBuffer + 51) ) = setVal->rateRawZ;
    *( (S16*)(tcBuffer + 55) ) = setVal->wheelRawX;
    *( (S16*)(tcBuffer + 57) ) = setVal->wheelRawY;
    *( (S16*)(tcBuffer + 59) ) = setVal->wheelRawZ;
    *( (S16*)(tcBuffer + 61) ) = setVal->star1CameraX;
    *( (S16*)(tcBuffer + 63) ) = setVal->star1CameraY;
    *( (S16*)(tcBuffer + 65) ) = setVal->star1CameraZ;
    *( (S16*)(tcBuffer + 67) ) = setVal->star1InertialX;
    *( (S16*)(tcBuffer + 69) ) = setVal->star1InertialY;
    *( (S16*)(tcBuffer + 71) ) = setVal->star1InertialZ;
    *( (S16*)(tcBuffer + 73) ) = setVal->star2CameraX;
    *( (S16*)(tcBuffer + 75) ) = setVal->star2CameraY;
    *( (S16*)(tcBuffer + 77) ) = setVal->star2CameraZ;
    *( (S16*)(tcBuffer + 79) ) = setVal->star2InertialX;
    *( (S16*)(tcBuffer + 81) ) = setVal->star2InertialY;
    *( (S16*)(tcBuffer + 83) ) = setVal->star2InertialZ;
    *( (S16*)(tcBuffer + 85) ) = setVal->star3CameraX;
    *( (S16*)(tcBuffer + 87) ) = setVal->star3CameraY;
    *( (S16*)(tcBuffer + 89) ) = setVal->star3CameraZ;
    *( (S16*)(tcBuffer + 91) ) = setVal->star3InertialX;
    *( (S16*)(tcBuffer + 93) ) = setVal->star3InertialY;
    *( (S16*)(tcBuffer + 95) ) = setVal->star3InertialZ;
    *( (U16*)(tcBuffer + 98) ) = setVal->gpsWeek;
    *( (U32*)(tcBuffer + 100) ) = setVal->gpsTimeMs;
    *( (S32*)(tcBuffer + 104) ) = setVal->posEcefX;
    *( (S16*)(tcBuffer + 108) ) = setVal->velEcefX;
    *( (S32*)(tcBuffer + 110) ) = setVal->posEcefY;
    *( (S16*)(tcBuffer + 114) ) = setVal->velEcefY;
    *( (S32*)(tcBuffer + 116) ) = setVal->posEcefZ;
    *( (S16*)(tcBuffer + 120) ) = setVal->velEcefZ;
    *( (U8*)(tcBuffer + 122) ) = (U8) round(setVal->stdDevPosX*10.0);
    *( (U8*)(tcBuffer + 123) ) = (U8) round(setVal->stdDevPosY*10.0);
    *( (U8*)(tcBuffer + 124) ) = (U8) round(setVal->stdDevPosZ*10.0);
    *( (U8*)(tcBuffer + 125) ) = setVal->stdDevVelX;
    *( (U8*)(tcBuffer + 126) ) = setVal->stdDevVelY;
    *( (U8*)(tcBuffer + 127) ) = setVal->stdDevVelZ;

    return 128;
}

uint16_t CUBEACP_FormatUserConEstParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 29;

    memcpy(tcBuffer + 1,setVal->userConSettings,48);
    memcpy(tcBuffer + 49,setVal->userEstSettings,48);

    return 97;
}

uint16_t CUBEACP_FormatWheelConfigCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 22;

    tcBuffer[1] = 
        (setVal->rW1Conf << 0);

    return 5;
}

uint16_t CUBEACP_FormatWheelSpeedCmdCmd(uint8_t* tcBuffer, CUBEACP_WheelSpeedCmd_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 17;

    *( (S16*)(tcBuffer + 1) ) = setVal->wheelX;
    *( (S16*)(tcBuffer + 3) ) = setVal->wheelY;
    *( (S16*)(tcBuffer + 5) ) = setVal->wheelZ;

    return 7;
}

uint16_t CUBEACP_FormatYWheelParamsCmd(uint8_t* tcBuffer, CUBEACP_AdcsConfig_t* setVal)
{
    // write TtcMessage ID to first element in buffer
    tcBuffer[0] = 39;

    *( (F32*)(tcBuffer + 1) ) = setVal->kh;
    *( (F32*)(tcBuffer + 5) ) = setVal->kn;
    *( (F32*)(tcBuffer + 9) ) = setVal->kp1;
    *( (F32*)(tcBuffer + 13) ) = setVal->kd1;
    *( (F32*)(tcBuffer + 17) ) = setVal->h_ref;

    return 21;
}


