it appears to work well now
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/tasks/SemaphoreFactory.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <fsfw_hal/common/spi/spiCommon.h>
|
||||
#include <fsfw_hal/linux/utility.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -32,11 +33,14 @@ ReturnValue_t RwPollingTask::performOperation(uint8_t operationCode) {
|
||||
state = InternalState::IDLE;
|
||||
ipcLock->unlockMutex();
|
||||
semaphore->acquire();
|
||||
// This loop takes 50 ms on a debug build.
|
||||
// Stopwatch watch;
|
||||
TaskFactory::delayTask(5);
|
||||
int fd = 0;
|
||||
for (auto& skip : skipCommandingForRw) {
|
||||
skip = false;
|
||||
}
|
||||
setAllReadFlagsFalse();
|
||||
ReturnValue_t result = openSpi(O_RDWR, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
continue;
|
||||
@ -55,27 +59,26 @@ ReturnValue_t RwPollingTask::performOperation(uint8_t operationCode) {
|
||||
}
|
||||
}
|
||||
closeSpi(fd);
|
||||
usleep(rws::SPI_REPLY_DELAY);
|
||||
if (readAllRws(rws::SET_SPEED) != returnvalue::OK) {
|
||||
continue;
|
||||
}
|
||||
// prepareSimpleCommand(rws::GET_LAST_RESET_STATUS);
|
||||
// if (writeAndReadAllRws(rws::GET_LAST_RESET_STATUS) != returnvalue::OK) {
|
||||
// continue;
|
||||
// }
|
||||
// prepareSimpleCommand(rws::GET_RW_STATUS);
|
||||
// if (writeAndReadAllRws(rws::GET_RW_STATUS) != returnvalue::OK) {
|
||||
// continue;
|
||||
// }
|
||||
// prepareSimpleCommand(rws::GET_TEMPERATURE);
|
||||
// if (writeAndReadAllRws(rws::GET_TEMPERATURE) != returnvalue::OK) {
|
||||
// continue;
|
||||
// }
|
||||
// prepareSimpleCommand(rws::CLEAR_LAST_RESET_STATUS);
|
||||
// if (writeAndReadAllRws(rws::CLEAR_LAST_RESET_STATUS) != returnvalue::OK) {
|
||||
// continue;
|
||||
// }
|
||||
// handleSpecialRequests();
|
||||
prepareSimpleCommand(rws::GET_LAST_RESET_STATUS);
|
||||
if (writeAndReadAllRws(rws::GET_LAST_RESET_STATUS) != returnvalue::OK) {
|
||||
continue;
|
||||
}
|
||||
prepareSimpleCommand(rws::GET_RW_STATUS);
|
||||
if (writeAndReadAllRws(rws::GET_RW_STATUS) != returnvalue::OK) {
|
||||
continue;
|
||||
}
|
||||
prepareSimpleCommand(rws::GET_TEMPERATURE);
|
||||
if (writeAndReadAllRws(rws::GET_TEMPERATURE) != returnvalue::OK) {
|
||||
continue;
|
||||
}
|
||||
prepareSimpleCommand(rws::CLEAR_LAST_RESET_STATUS);
|
||||
if (writeAndReadAllRws(rws::CLEAR_LAST_RESET_STATUS) != returnvalue::OK) {
|
||||
continue;
|
||||
}
|
||||
handleSpecialRequests();
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
@ -188,7 +191,6 @@ ReturnValue_t RwPollingTask::writeAndReadAllRws(DeviceCommandId_t id) {
|
||||
}
|
||||
|
||||
closeSpi(fd);
|
||||
usleep(rws::SPI_REPLY_DELAY);
|
||||
return readAllRws(id);
|
||||
}
|
||||
|
||||
@ -208,50 +210,39 @@ ReturnValue_t RwPollingTask::readNextReply(RwCookie& rwCookie, uint8_t* replyBuf
|
||||
int fd = 0;
|
||||
gpioId_t gpioId = rwCookie.getChipSelectPin();
|
||||
uint8_t byteRead = 0;
|
||||
bool exitOuter = false;
|
||||
for (unsigned retryIdx = 0; retryIdx < MAX_RETRIES_REPLY; retryIdx++) {
|
||||
/**
|
||||
* The reaction wheel responds with empty frames while preparing the reply data.
|
||||
* However, receiving more than 5 empty frames will be interpreted as an error.
|
||||
*/
|
||||
for (int idx = 0; idx < 5; idx++) {
|
||||
result = openSpi(O_RDWR, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
pullCsLow(gpioId, gpioIF);
|
||||
if (read(fd, &byteRead, 1) != 1) {
|
||||
sif::error << "RwPollingTask: Read failed. " << strerror(errno) << std::endl;
|
||||
pullCsHigh(gpioId, gpioIF);
|
||||
closeSpi(fd);
|
||||
return rws::SPI_READ_FAILURE;
|
||||
}
|
||||
if (idx == 0) {
|
||||
if (byteRead != rws::FRAME_DELIMITER) {
|
||||
sif::error << "Invalid data, expected start marker, got " << (int)byteRead << std::endl;
|
||||
pullCsHigh(gpioId, gpioIF);
|
||||
closeSpi(fd);
|
||||
return rws::NO_START_MARKER;
|
||||
}
|
||||
}
|
||||
|
||||
if (byteRead != rws::FRAME_DELIMITER) {
|
||||
exitOuter = true;
|
||||
break;
|
||||
}
|
||||
result = openSpi(O_RDWR, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
pullCsLow(gpioId, gpioIF);
|
||||
bool lastByteWasFrameMarker = false;
|
||||
Countdown cd(3000);
|
||||
size_t readIdx = 0;
|
||||
|
||||
while (true) {
|
||||
lastByteWasFrameMarker = false;
|
||||
if (read(fd, &byteRead, 1) != 1) {
|
||||
sif::error << "RwPollingTask: Read failed. " << strerror(errno) << std::endl;
|
||||
pullCsHigh(gpioId, gpioIF);
|
||||
closeSpi(fd);
|
||||
if (idx == MAX_RETRIES_REPLY - 1) {
|
||||
sif::error << "rwSpiCallback::spiCallback: Empty frame timeout" << std::endl;
|
||||
return rws::NO_REPLY;
|
||||
}
|
||||
return rws::SPI_READ_FAILURE;
|
||||
}
|
||||
if(exitOuter) {
|
||||
if (byteRead == rws::FRAME_DELIMITER) {
|
||||
lastByteWasFrameMarker = true;
|
||||
}
|
||||
// Start of frame detected.
|
||||
if (byteRead != rws::FRAME_DELIMITER and not lastByteWasFrameMarker) {
|
||||
break;
|
||||
}
|
||||
TaskFactory::delayTask(5);
|
||||
|
||||
if (readIdx % 100 == 0 && cd.hasTimedOut()) {
|
||||
pullCsHigh(gpioId, gpioIF);
|
||||
closeSpi(fd);
|
||||
return rws::SPI_READ_FAILURE;
|
||||
}
|
||||
readIdx++;
|
||||
}
|
||||
|
||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||
sif::info << "RW start marker detected" << std::endl;
|
||||
#endif
|
||||
@ -339,13 +330,14 @@ ReturnValue_t RwPollingTask::readAllRws(DeviceCommandId_t id) {
|
||||
if (((id == rws::SET_SPEED) and !rwCookies[idx]->setSpeed) or skipCommandingForRw[idx]) {
|
||||
continue;
|
||||
}
|
||||
if (spiLock == nullptr) {
|
||||
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
uint8_t* replyBuf;
|
||||
size_t maxReadLen = idAndIdxToReadBuffer(id, idx, &replyBuf);
|
||||
readNextReply(*rwCookies[idx], replyBuf, maxReadLen);
|
||||
ReturnValue_t result = readNextReply(*rwCookies[idx], replyBuf + 1, maxReadLen);
|
||||
if (result == returnvalue::OK) {
|
||||
// The first byte is always a flag which shows whether the value was read
|
||||
// properly at least once.
|
||||
replyBuf[0] = true;
|
||||
}
|
||||
}
|
||||
// SPI is closed in readNextReply as well.
|
||||
return returnvalue::OK;
|
||||
@ -440,6 +432,19 @@ void RwPollingTask::handleSpecialRequests() {
|
||||
}
|
||||
}
|
||||
|
||||
void RwPollingTask::setAllReadFlagsFalse() {
|
||||
for (auto& rwCookie : rwCookies) {
|
||||
RwReplies replies(rwCookie->replyBuf.data());
|
||||
replies.getLastResetStatusReply[0] = false;
|
||||
replies.clearLastResetStatusReply[0] = false;
|
||||
replies.hkDataReply[0] = false;
|
||||
replies.readTemperatureReply[0] = false;
|
||||
replies.rwStatusReply[0] = false;
|
||||
replies.setSpeedReply[0] = false;
|
||||
replies.initRwControllerReply[0] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// This closes the SPI
|
||||
void RwPollingTask::closeSpi(int fd) {
|
||||
// This will perform the function to close the SPI
|
||||
@ -453,10 +458,10 @@ ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
||||
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
pullCsLow(gpioId, gpioIF);
|
||||
// Add datalinklayer like specified in the datasheet.
|
||||
size_t lenToSend = 0;
|
||||
rws::encodeHdlc(writeBuffer.data(), writeLen, encodedBuffer.data(), lenToSend);
|
||||
pullCsLow(gpioId, gpioIF);
|
||||
if (write(fd, encodedBuffer.data(), lenToSend) != static_cast<ssize_t>(lenToSend)) {
|
||||
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
||||
pullCsHigh(gpioId, gpioIF);
|
||||
@ -513,7 +518,7 @@ ReturnValue_t RwPollingTask::prepareSetSpeedCmd(uint8_t rwIdx) {
|
||||
speedToSet = rwCookies[rwIdx]->currentRwSpeed;
|
||||
rampTimeToSet = rwCookies[rwIdx]->currentRampTime;
|
||||
}
|
||||
size_t serLen = 0;
|
||||
size_t serLen = 1;
|
||||
SerializeAdapter::serialize(&speedToSet, &serPtr, &serLen, writeBuffer.size(),
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
SerializeAdapter::serialize(&rampTimeToSet, &serPtr, &serLen, writeBuffer.size(),
|
||||
|
@ -80,6 +80,7 @@ class RwPollingTask : public SystemObject, public ExecutableObjectIF, public Dev
|
||||
|
||||
size_t idAndIdxToReadBuffer(DeviceCommandId_t id, uint8_t rwIdx, uint8_t** readPtr);
|
||||
void fillSpecialRequestArray();
|
||||
void setAllReadFlagsFalse();
|
||||
|
||||
void pullCsHigh(gpioId_t gpioId, GpioIF& gpioIF);
|
||||
void closeSpi(int);
|
||||
|
Reference in New Issue
Block a user