#include "MGMHandlerRM3100.h" #include #include #include MGMHandlerRM3100::MGMHandlerRM3100(object_id_t objectId, object_id_t deviceCommunication, CookieIF* comCookie): DeviceHandlerBase(objectId, deviceCommunication, comCookie) { } MGMHandlerRM3100::~MGMHandlerRM3100() {} void MGMHandlerRM3100::doStartUp() { if(internalState == STATE_NONE) { internalState = STATE_CONFIGURE_CMM; } if(internalState == STATE_CONFIGURE_CMM) { internalState = STATE_READ_CMM; } else if(internalState == STATE_READ_CMM) { if(commandExecuted) { internalState = STATE_CONFIGURE_TMRC; } } if(internalState == STATE_CONFIGURE_TMRC) { internalState = STATE_READ_TMRC; } else if(internalState == STATE_READ_TMRC) { if(commandExecuted) { internalState = STATE_NORMAL; setMode(_MODE_TO_ON); } } } void MGMHandlerRM3100::doShutDown() { setMode(_MODE_POWER_DOWN); } ReturnValue_t MGMHandlerRM3100::buildTransitionDeviceCommand( DeviceCommandId_t *id) { if(internalState == STATE_CONFIGURE_CMM) { *id = RM3100::CONFIGURE_CMM; } if(internalState == STATE_READ_CMM) { *id = RM3100::READ_CMM; } if(internalState == STATE_CONFIGURE_TMRC) { *id = RM3100::CONFIGURE_TMRC; } if(internalState == STATE_READ_TMRC) { *id = RM3100::READ_TMRC; } return buildCommandFromCommand(*id, nullptr, 0); } ReturnValue_t MGMHandlerRM3100::buildCommandFromCommand( DeviceCommandId_t deviceCommand, const uint8_t *commandData, size_t commandDataLen) { switch(deviceCommand) { case(RM3100::CONFIGURE_CMM): { commandBuffer[0] = RM3100::CMM_REGISTER; commandBuffer[1] = RM3100::CMM_VALUE; rawPacket = commandBuffer; rawPacketLen = 2; break; } case(RM3100::READ_CMM): { commandBuffer[0] = RM3100::CMM_REGISTER | RM3100::READ_MASK; commandBuffer[1] = 0; rawPacket = commandBuffer; rawPacketLen = 2; break; } case(RM3100::CONFIGURE_TMRC): { return handleTmrcConfigCommand(deviceCommand, commandData, commandDataLen); } case(RM3100::READ_TMRC): { commandBuffer[0] = RM3100::TMRC_REGISTER | RM3100::READ_MASK; commandBuffer[1] = 0; rawPacket = commandBuffer; rawPacketLen = 2; break; } case(RM3100::CONFIGURE_CYCLE_COUNT): { return handleCycleCountConfigCommand(deviceCommand, commandData, commandDataLen); } case(RM3100::READ_CYCLE_COUNT): { commandBuffer[0] = RM3100::CYCLE_COUNT_START_REGISTER | RM3100::READ_MASK; std::memset(commandBuffer + 1, 0, 6); rawPacket = commandBuffer; rawPacketLen = 7; break; } case(RM3100::READ_DATA): { commandBuffer[0] = RM3100::MEASUREMENT_REG_START | RM3100::READ_MASK; std::memset(commandBuffer + 1, 0, 9); rawPacketLen = 10; break; } default: return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } return RETURN_OK; } ReturnValue_t MGMHandlerRM3100::buildNormalDeviceCommand( DeviceCommandId_t *id) { *id = RM3100::READ_DATA; return buildCommandFromCommand(*id, nullptr, 0); } ReturnValue_t MGMHandlerRM3100::scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) { // SPI, ID will always be the one of the last sent command. *foundId = this->getPendingCommand(); *foundLen = this->rawPacketLen; // Data with SPI Interface has always this answer if (start[0] == 0b11111111) { return RETURN_OK; } else { return DeviceHandlerIF::INVALID_DATA; } } ReturnValue_t MGMHandlerRM3100::interpretDeviceReply( DeviceCommandId_t id, const uint8_t *packet) { if(id == RM3100::READ_CMM) { if(packet[1] == cmmRegValue) { commandExecuted = true; } else { // Attempt reconfiguration. internalState = STATE_CONFIGURE_CMM; return DeviceHandlerIF::DEVICE_REPLY_INVALID; } } else if(id == RM3100::READ_TMRC) { if(packet[1] == tmrcRegValue) { commandExecuted = true; // Reading TMRC was commanded. if(mode == MODE_NORMAL) { } } else { // Attempt reconfiguration. internalState = STATE_CONFIGURE_TMRC; return DeviceHandlerIF::DEVICE_REPLY_INVALID; } } else if(id == RM3100::READ_DATA) { // analyze data here. // Field strengths in micro Tesla int32_t fieldStrengthX = (packet[1] << 16 | packet[2] << 8 | packet[3]) * scaleFactorX; int32_t fieldStrengthY = (packet[4] << 16 | packet[5] << 8 | packet[6]) * scaleFactorY; int32_t fieldStrengthZ = (packet[7] << 16 | packet[8] << 8 | packet[9]) * scaleFactorZ; } else { return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; } return RETURN_OK; } ReturnValue_t MGMHandlerRM3100::handleCycleCountConfigCommand( DeviceCommandId_t deviceCommand, const uint8_t *commandData, size_t commandDataLen) { if(commandData == nullptr) { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } // Set cycle count if(commandDataLen == 2) { handleCycleCommand(true, commandData, commandDataLen); } else if(commandDataLen == 6) { handleCycleCommand(false, commandData, commandDataLen); } else { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } commandBuffer[0] = RM3100::CYCLE_COUNT_VALUE; std::memcpy(commandBuffer + 1, &cycleCountRegValueX, 2); std::memcpy(commandBuffer + 3, &cycleCountRegValueY, 2); std::memcpy(commandBuffer + 5, &cycleCountRegValueZ, 2); rawPacketLen = 7; rawPacket = commandBuffer; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t MGMHandlerRM3100::handleCycleCommand(bool oneCycleValue, const uint8_t *commandData, size_t commandDataLen) { RM3100::CycleCountCommand command(oneCycleValue); ReturnValue_t result = command.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } // Data sheet p.30 // "while noise limits the useful upper range to ~400 cycle counts." if(command.cycleCountX > 450 ) { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } if(not oneCycleValue and (command.cycleCountY > 450 or command.cycleCountZ > 450)) { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } cycleCountRegValueX = command.cycleCountX; cycleCountRegValueY = command.cycleCountY; cycleCountRegValueZ = command.cycleCountZ; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t MGMHandlerRM3100::handleTmrcConfigCommand( DeviceCommandId_t deviceCommand, const uint8_t *commandData, size_t commandDataLen) { if(commandData == nullptr) { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } if(commandDataLen != 1) { return DeviceHandlerIF::INVALID_COMMAND_PARAMETER; } commandBuffer[0] = RM3100::TMRC_REGISTER; commandBuffer[1] = commandData[1]; rawPacketLen = 2; rawPacket = commandBuffer; return HasReturnvaluesIF::RETURN_OK; }