|
|
|
@ -71,11 +71,7 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_
|
|
|
|
|
return returnvalue::OK;
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
// Might be a configuration error
|
|
|
|
|
sif::debug << "GyroADIS16507Handler::buildTransitionDeviceCommand: "
|
|
|
|
|
"Unknown internal state!"
|
|
|
|
|
<< std::endl;
|
|
|
|
|
return returnvalue::OK;
|
|
|
|
|
return NOTHING_TO_SEND;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return returnvalue::OK;
|
|
|
|
@ -84,106 +80,12 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_
|
|
|
|
|
ReturnValue_t GyrAdis1650XHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
|
|
|
|
const uint8_t *commandData,
|
|
|
|
|
size_t commandDataLen) {
|
|
|
|
|
// switch (deviceCommand) {
|
|
|
|
|
// case (adis1650x::READ_OUT_CONFIG): {
|
|
|
|
|
// this->rawPacketLen = adis1650x::CONFIG_READOUT_SIZE;
|
|
|
|
|
// uint8_t regList[6] = {};
|
|
|
|
|
// regList[0] = adis1650x::DIAG_STAT_REG;
|
|
|
|
|
// regList[1] = adis1650x::FILTER_CTRL_REG;
|
|
|
|
|
// regList[2] = adis1650x::RANG_MDL_REG;
|
|
|
|
|
// regList[3] = adis1650x::MSC_CTRL_REG;
|
|
|
|
|
// regList[4] = adis1650x::DEC_RATE_REG;
|
|
|
|
|
// regList[5] = adis1650x::PROD_ID_REG;
|
|
|
|
|
// adis1650x::prepareReadCommand(regList, sizeof(regList), commandBuffer.data(),
|
|
|
|
|
// commandBuffer.size());
|
|
|
|
|
// this->rawPacket = commandBuffer.data();
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::READ_SENSOR_DATA): {
|
|
|
|
|
// if (breakCountdown.isBusy()) {
|
|
|
|
|
// // A glob command is pending and sensor data can't be read currently
|
|
|
|
|
// return NO_REPLY_EXPECTED;
|
|
|
|
|
// }
|
|
|
|
|
// std::memcpy(commandBuffer.data(), adis1650x::BURST_READ_ENABLE.data(),
|
|
|
|
|
// adis1650x::BURST_READ_ENABLE.size());
|
|
|
|
|
// std::memset(commandBuffer.data() + 2, 0, 10 * 2);
|
|
|
|
|
// this->rawPacketLen = adis1650x::SENSOR_READOUT_SIZE;
|
|
|
|
|
// this->rawPacket = commandBuffer.data();
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// TODO: Convert to special request
|
|
|
|
|
|
|
|
|
|
// case (adis1650x::SELF_TEST_SENSORS): {
|
|
|
|
|
// if (breakCountdown.isBusy()) {
|
|
|
|
|
// // Another glob command is pending
|
|
|
|
|
// return HasActionsIF::IS_BUSY;
|
|
|
|
|
// }
|
|
|
|
|
// prepareWriteCommand(adis1650x::GLOB_CMD, adis1650x::GlobCmds::SENSOR_SELF_TEST, 0x00);
|
|
|
|
|
// breakCountdown.setTimeout(adis1650x::SELF_TEST_BREAK);
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::SELF_TEST_MEMORY): {
|
|
|
|
|
// if (breakCountdown.isBusy()) {
|
|
|
|
|
// // Another glob command is pending
|
|
|
|
|
// return HasActionsIF::IS_BUSY;
|
|
|
|
|
// }
|
|
|
|
|
// prepareWriteCommand(adis1650x::GLOB_CMD, adis1650x::GlobCmds::FLASH_MEMORY_TEST, 0x00);
|
|
|
|
|
// breakCountdown.setTimeout(adis1650x::FLASH_MEMORY_TEST_BREAK);
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::UPDATE_NV_CONFIGURATION): {
|
|
|
|
|
// if (breakCountdown.isBusy()) {
|
|
|
|
|
// // Another glob command is pending
|
|
|
|
|
// return HasActionsIF::IS_BUSY;
|
|
|
|
|
// }
|
|
|
|
|
// prepareWriteCommand(adis1650x::GLOB_CMD, adis1650x::GlobCmds::FLASH_MEMORY_UPDATE,
|
|
|
|
|
// 0x00); breakCountdown.setTimeout(adis1650x::FLASH_MEMORY_UPDATE_BREAK); break;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::RESET_SENSOR_CONFIGURATION): {
|
|
|
|
|
// if (breakCountdown.isBusy()) {
|
|
|
|
|
// // Another glob command is pending
|
|
|
|
|
// return HasActionsIF::IS_BUSY;
|
|
|
|
|
// }
|
|
|
|
|
// prepareWriteCommand(adis1650x::GLOB_CMD, adis1650x::GlobCmds::FACTORY_CALIBRATION,
|
|
|
|
|
// 0x00); breakCountdown.setTimeout(adis1650x::FACTORY_CALIBRATION_BREAK); break;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::SW_RESET): {
|
|
|
|
|
// if (breakCountdown.isBusy()) {
|
|
|
|
|
// // Another glob command is pending
|
|
|
|
|
// return HasActionsIF::IS_BUSY;
|
|
|
|
|
// }
|
|
|
|
|
// prepareWriteCommand(adis1650x::GLOB_CMD, adis1650x::GlobCmds::SOFTWARE_RESET, 0x00);
|
|
|
|
|
// breakCountdown.setTimeout(adis1650x::SW_RESET_BREAK);
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::PRINT_CURRENT_CONFIGURATION): {
|
|
|
|
|
//#if OBSW_VERBOSE_LEVEL >= 1
|
|
|
|
|
// PoolReadGuard pg(&configDataset);
|
|
|
|
|
// sif::info << "ADIS16507 Sensor configuration: DIAG_STAT: 0x" << std::hex << std::setw(4)
|
|
|
|
|
// << std::setfill('0') << "0x" << configDataset.diagStatReg.value << std::endl;
|
|
|
|
|
// sif::info << "MSC_CTRL: " << std::hex << std::setw(4) << "0x"
|
|
|
|
|
// << configDataset.mscCtrlReg.value << " | FILT_CTRL: 0x"
|
|
|
|
|
// << configDataset.filterSetting.value << " | DEC_RATE: 0x"
|
|
|
|
|
// << configDataset.decRateReg.value << std::setfill(' ') << std::endl;
|
|
|
|
|
//#endif /* OBSW_VERBOSE_LEVEL >= 1 */
|
|
|
|
|
//
|
|
|
|
|
//}
|
|
|
|
|
//}
|
|
|
|
|
// return returnvalue::OK;
|
|
|
|
|
return NOTHING_TO_SEND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GyrAdis1650XHandler::fillCommandAndReplyMap() {
|
|
|
|
|
insertInCommandMap(adis1650x::REQUEST);
|
|
|
|
|
insertInReplyMap(adis1650x::REPLY, 5, nullptr, 0, true);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::READ_SENSOR_DATA, 1, &primaryDataset);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::READ_OUT_CONFIG, 1, &configDataset);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::SELF_TEST_SENSORS, 1);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::SELF_TEST_MEMORY, 1);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::UPDATE_NV_CONFIGURATION, 1);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::RESET_SENSOR_CONFIGURATION, 1);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::SW_RESET, 1);
|
|
|
|
|
// insertInCommandAndReplyMap(adis1650x::PRINT_CURRENT_CONFIGURATION, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t remainingSize,
|
|
|
|
@ -197,7 +99,9 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
|
|
|
|
|
}
|
|
|
|
|
*foundId = adis1650x::REPLY;
|
|
|
|
|
*foundLen = remainingSize;
|
|
|
|
|
|
|
|
|
|
if (internalState == InternalState::SHUTDOWN) {
|
|
|
|
|
commandExecuted = true;
|
|
|
|
|
}
|
|
|
|
|
return returnvalue::OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -263,94 +167,6 @@ LocalPoolDataSetBase *GyrAdis1650XHandler::getDataSetHandle(sid_t sid) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReturnValue_t GyroADIS1650XHandler::handleSensorData(const uint8_t *packet) {
|
|
|
|
|
// using namespace adis1650x;
|
|
|
|
|
// BurstModes burstMode = getBurstMode();
|
|
|
|
|
// switch (burstMode) {
|
|
|
|
|
// case (BurstModes::BURST_16_BURST_SEL_1):
|
|
|
|
|
// case (BurstModes::BURST_32_BURST_SEL_1): {
|
|
|
|
|
// sif::warning << "GyroADIS1650XHandler::interpretDeviceReply: Analysis with BURST_SEL1"
|
|
|
|
|
// " not implemented!"
|
|
|
|
|
// << std::endl;
|
|
|
|
|
// return returnvalue::OK;
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::BurstModes::BURST_16_BURST_SEL_0): {
|
|
|
|
|
// uint16_t checksum = packet[20] << 8 | packet[21];
|
|
|
|
|
// // Now verify the read checksum with the expected checksum according to datasheet p. 20
|
|
|
|
|
// uint16_t calcChecksum = 0;
|
|
|
|
|
// for (size_t idx = 2; idx < 20; idx++) {
|
|
|
|
|
// calcChecksum += packet[idx];
|
|
|
|
|
// }
|
|
|
|
|
// if (checksum != calcChecksum) {
|
|
|
|
|
//#if OBSW_VERBOSE_LEVEL >= 1
|
|
|
|
|
// sif::warning << "GyroADIS1650XHandler::interpretDeviceReply: "
|
|
|
|
|
// "Invalid checksum detected!"
|
|
|
|
|
// << std::endl;
|
|
|
|
|
//#endif
|
|
|
|
|
// return returnvalue::FAILED;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// ReturnValue_t result = configDataset.diagStatReg.read();
|
|
|
|
|
// if (result == returnvalue::OK) {
|
|
|
|
|
// configDataset.diagStatReg.value = packet[2] << 8 | packet[3];
|
|
|
|
|
// configDataset.diagStatReg.setValid(true);
|
|
|
|
|
// }
|
|
|
|
|
// configDataset.diagStatReg.commit();
|
|
|
|
|
//
|
|
|
|
|
// {
|
|
|
|
|
// PoolReadGuard pg(&primaryDataset);
|
|
|
|
|
// int16_t angVelocXRaw = packet[4] << 8 | packet[5];
|
|
|
|
|
// primaryDataset.angVelocX.value = static_cast<float>(angVelocXRaw) * sensitivity;
|
|
|
|
|
// int16_t angVelocYRaw = packet[6] << 8 | packet[7];
|
|
|
|
|
// primaryDataset.angVelocY.value = static_cast<float>(angVelocYRaw) * sensitivity;
|
|
|
|
|
// int16_t angVelocZRaw = packet[8] << 8 | packet[9];
|
|
|
|
|
// primaryDataset.angVelocZ.value = static_cast<float>(angVelocZRaw) * sensitivity;
|
|
|
|
|
//
|
|
|
|
|
// float accelScaling = 0;
|
|
|
|
|
// if (adisType == adis1650x::Type::ADIS16507) {
|
|
|
|
|
// accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
|
|
|
|
|
// } else if (adisType == adis1650x::Type::ADIS16505) {
|
|
|
|
|
// accelScaling = adis1650x::ACCELEROMETER_RANGE_16505;
|
|
|
|
|
// } else {
|
|
|
|
|
// sif::warning << "GyroADIS1650XHandler::handleSensorData: "
|
|
|
|
|
// "Unknown ADIS type"
|
|
|
|
|
// << std::endl;
|
|
|
|
|
// }
|
|
|
|
|
// int16_t accelXRaw = packet[10] << 8 | packet[11];
|
|
|
|
|
// primaryDataset.accelX.value = static_cast<float>(accelXRaw) / INT16_MAX * accelScaling;
|
|
|
|
|
// int16_t accelYRaw = packet[12] << 8 | packet[13];
|
|
|
|
|
// primaryDataset.accelY.value = static_cast<float>(accelYRaw) / INT16_MAX * accelScaling;
|
|
|
|
|
// int16_t accelZRaw = packet[14] << 8 | packet[15];
|
|
|
|
|
// primaryDataset.accelZ.value = static_cast<float>(accelZRaw) / INT16_MAX * accelScaling;
|
|
|
|
|
//
|
|
|
|
|
// int16_t temperatureRaw = packet[16] << 8 | packet[17];
|
|
|
|
|
// primaryDataset.temperature.value = static_cast<float>(temperatureRaw) * 0.1;
|
|
|
|
|
// // Ignore data counter for now
|
|
|
|
|
// primaryDataset.setValidity(true, true);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (periodicPrintout) {
|
|
|
|
|
// if (debugDivider.checkAndIncrement()) {
|
|
|
|
|
// sif::info << "GyroADIS1650XHandler: Angular velocities in deg / s" << std::endl;
|
|
|
|
|
// sif::info << "X: " << primaryDataset.angVelocX.value << std::endl;
|
|
|
|
|
// sif::info << "Y: " << primaryDataset.angVelocY.value << std::endl;
|
|
|
|
|
// sif::info << "Z: " << primaryDataset.angVelocZ.value << std::endl;
|
|
|
|
|
// sif::info << "GyroADIS1650XHandler: Accelerations in m / s^2: " << std::endl;
|
|
|
|
|
// sif::info << "X: " << primaryDataset.accelX.value << std::endl;
|
|
|
|
|
// sif::info << "Y: " << primaryDataset.accelY.value << std::endl;
|
|
|
|
|
// sif::info << "Z: " << primaryDataset.accelZ.value << std::endl;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// case (BurstModes::BURST_32_BURST_SEL_0): {
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return returnvalue::OK;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
uint32_t GyrAdis1650XHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 6000; }
|
|
|
|
|
|
|
|
|
|
void GyrAdis1650XHandler::prepareWriteCommand(uint8_t startReg, uint8_t valueOne,
|
|
|
|
@ -394,108 +210,6 @@ adis1650x::BurstModes GyrAdis1650XHandler::getBurstMode() {
|
|
|
|
|
return adis1650x::burstModeFromMscCtrl(currentCtrlReg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#ifdef FSFW_OSAL_LINUX
|
|
|
|
|
|
|
|
|
|
// ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie *cookie,
|
|
|
|
|
// const uint8_t *sendData, size_t sendLen,
|
|
|
|
|
// void *args) {
|
|
|
|
|
// GyroADIS1650XHandler *handler = reinterpret_cast<GyroADIS1650XHandler *>(args);
|
|
|
|
|
// if (handler == nullptr) {
|
|
|
|
|
// sif::error << "GyroADIS16507Handler::spiSendCallback: Passed handler pointer is invalid!"
|
|
|
|
|
// << std::endl;
|
|
|
|
|
// return returnvalue::FAILED;
|
|
|
|
|
// }
|
|
|
|
|
// DeviceCommandId_t currentCommand = handler->getPendingCommand();
|
|
|
|
|
// switch (currentCommand) {
|
|
|
|
|
// case (adis1650x::READ_SENSOR_DATA): {
|
|
|
|
|
// return comIf->performRegularSendOperation(cookie, sendData, sendLen);
|
|
|
|
|
// }
|
|
|
|
|
// case (adis1650x::READ_OUT_CONFIG):
|
|
|
|
|
// default: {
|
|
|
|
|
// ReturnValue_t result = returnvalue::OK;
|
|
|
|
|
// int retval = 0;
|
|
|
|
|
// // Prepare transfer
|
|
|
|
|
// int fileDescriptor = 0;
|
|
|
|
|
// std::string device = comIf->getSpiDev();
|
|
|
|
|
// UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
|
|
|
|
// if (fileHelper.getOpenResult() != returnvalue::OK) {
|
|
|
|
|
// return SpiComIF::OPENING_FILE_FAILED;
|
|
|
|
|
// }
|
|
|
|
|
// spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
|
|
|
|
// uint32_t spiSpeed = 0;
|
|
|
|
|
// cookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
|
|
|
|
// comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
|
|
|
|
// cookie->assignWriteBuffer(sendData);
|
|
|
|
|
// cookie->setTransferSize(2);
|
|
|
|
|
//
|
|
|
|
|
// gpioId_t gpioId = cookie->getChipSelectPin();
|
|
|
|
|
// GpioIF &gpioIF = comIf->getGpioInterface();
|
|
|
|
|
// MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
|
|
|
|
// uint32_t timeoutMs = 0;
|
|
|
|
|
// MutexIF *mutex = comIf->getCsMutex();
|
|
|
|
|
// cookie->getMutexParams(timeoutType, timeoutMs);
|
|
|
|
|
// if (mutex == nullptr) {
|
|
|
|
|
//#if OBSW_VERBOSE_LEVEL >= 1
|
|
|
|
|
// sif::warning << "GyroADIS16507Handler::spiSendCallback: "
|
|
|
|
|
// "Mutex or GPIO interface invalid"
|
|
|
|
|
// << std::endl;
|
|
|
|
|
// return returnvalue::FAILED;
|
|
|
|
|
//#endif
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (gpioId != gpio::NO_GPIO) {
|
|
|
|
|
// result = mutex->lockMutex(timeoutType, timeoutMs);
|
|
|
|
|
// if (result != returnvalue::OK) {
|
|
|
|
|
//#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
// sif::error << "SpiComIF::sendMessage: Failed to lock mutex" << std::endl;
|
|
|
|
|
//#endif
|
|
|
|
|
// return result;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// size_t idx = 0;
|
|
|
|
|
// spi_ioc_transfer *transferStruct = cookie->getTransferStructHandle();
|
|
|
|
|
// uint64_t origTx = transferStruct->tx_buf;
|
|
|
|
|
// uint64_t origRx = transferStruct->rx_buf;
|
|
|
|
|
// while (idx < sendLen) {
|
|
|
|
|
// // Pull SPI CS low. For now, no support for active high given
|
|
|
|
|
// if (gpioId != gpio::NO_GPIO) {
|
|
|
|
|
// gpioIF.pullLow(gpioId);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // Execute transfer
|
|
|
|
|
// // Initiate a full duplex SPI transfer.
|
|
|
|
|
// retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
|
|
|
|
// if (retval < 0) {
|
|
|
|
|
// utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
|
|
|
|
// result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
|
|
|
|
// }
|
|
|
|
|
//#if FSFW_HAL_SPI_WIRETAPPING == 1
|
|
|
|
|
// comIf->performSpiWiretapping(cookie);
|
|
|
|
|
//#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
|
|
|
|
|
//
|
|
|
|
|
// if (gpioId != gpio::NO_GPIO) {
|
|
|
|
|
// gpioIF.pullHigh(gpioId);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// idx += 2;
|
|
|
|
|
// if (idx < sendLen) {
|
|
|
|
|
// usleep(adis1650x::STALL_TIME_MICROSECONDS);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// transferStruct->tx_buf += 2;
|
|
|
|
|
// transferStruct->rx_buf += 2;
|
|
|
|
|
// }
|
|
|
|
|
// transferStruct->tx_buf = origTx;
|
|
|
|
|
// transferStruct->rx_buf = origRx;
|
|
|
|
|
// if (gpioId != gpio::NO_GPIO) {
|
|
|
|
|
// mutex->unlockMutex();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return returnvalue::OK;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
void GyrAdis1650XHandler::setToGoToNormalModeImmediately() { goToNormalMode = true; }
|
|
|
|
|
|
|
|
|
|
void GyrAdis1650XHandler::enablePeriodicPrintouts(bool enable, uint8_t divider) {
|
|
|
|
|