Merge pull request 'PAPB multi-byte write support' (#543) from papb_multi_byte_write_support into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #543
This commit is contained in:
commit
013692cc41
@ -2,6 +2,7 @@
|
|||||||
#include <linux/ipcore/PapbVcInterface.h>
|
#include <linux/ipcore/PapbVcInterface.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
@ -27,11 +28,46 @@ ReturnValue_t PapbVcInterface::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
||||||
|
// There are no packets smaller than 4, this is considered a configuration error.
|
||||||
|
if (size < 4) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
if (pollInterfaceReadiness(0, true) == returnvalue::OK) {
|
if (pollInterfaceReadiness(0, true) == returnvalue::OK) {
|
||||||
startPacketTransfer();
|
startPacketTransfer(ByteWidthCfg::ONE);
|
||||||
} else {
|
} else {
|
||||||
return DirectTmSinkIF::IS_BUSY;
|
return DirectTmSinkIF::IS_BUSY;
|
||||||
}
|
}
|
||||||
|
// TODO: This should work but does not.. :(
|
||||||
|
// size_t idx = 0;
|
||||||
|
// while (idx < size) {
|
||||||
|
//
|
||||||
|
// nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
|
||||||
|
// if ((size - idx) < 4) {
|
||||||
|
// *vcBaseReg = CONFIG_DATA_INPUT | (size - idx - 1);
|
||||||
|
// usleep(1);
|
||||||
|
// }
|
||||||
|
// if (pollPapbBusySignal(2) == returnvalue::OK) {
|
||||||
|
// // vcBaseReg + DATA_REG_OFFSET + 3 = static_cast<uint8_t>(data + idx);
|
||||||
|
// // vcBaseReg + DATA_REG_OFFSET + 2 = static_cast<uint8_t>(data + idx + 1);
|
||||||
|
// // vcBaseReg + DATA_REG_OFFSET + 1 = static_cast<uint8_t>(data + idx + 2);
|
||||||
|
// // vcBaseReg + DATA_REG_OFFSET = static_cast<uint8_t>(data + idx + 3);
|
||||||
|
//
|
||||||
|
// // std::memcpy((vcBaseReg + DATA_REG_OFFSET), data + idx , nextWriteSize);
|
||||||
|
// *(vcBaseReg + DATA_REG_OFFSET) = *reinterpret_cast<const uint32_t*>(data + idx);
|
||||||
|
// //uint8_t* byteReg = reinterpret_cast<uint8_t*>(vcBaseReg + DATA_REG_OFFSET);
|
||||||
|
//
|
||||||
|
// //byteReg[0] = data[idx];
|
||||||
|
// //byteReg[1] = data[idx];
|
||||||
|
// } else {
|
||||||
|
// abortPacketTransfer();
|
||||||
|
// return returnvalue::FAILED;
|
||||||
|
// }
|
||||||
|
// // TODO: Change this after the bugfix. Right now, the PAPB ignores the content of the byte
|
||||||
|
// // width configuration.5
|
||||||
|
// // It's okay to increment by a larger amount for the last segment here, loop will be over
|
||||||
|
// // in any case.
|
||||||
|
// idx += 4;
|
||||||
|
// }
|
||||||
for (size_t idx = 0; idx < size; idx++) {
|
for (size_t idx = 0; idx < size; idx++) {
|
||||||
// This delay is super-important, DO NOT REMOVE!
|
// This delay is super-important, DO NOT REMOVE!
|
||||||
// Polling the GPIO or the config register too often messes up the scheduler.
|
// Polling the GPIO or the config register too often messes up the scheduler.
|
||||||
@ -56,14 +92,16 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
|
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
|
||||||
|
*vcBaseReg = CONFIG_DATA_INPUT | initWidth;
|
||||||
|
}
|
||||||
|
|
||||||
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
|
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
|
||||||
|
|
||||||
ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries,
|
ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries,
|
||||||
bool checkReadyState) const {
|
bool checkReadyState) const {
|
||||||
uint32_t busyIdx = 0;
|
uint32_t busyIdx = 0;
|
||||||
nextDelay.tv_nsec = FIRST_NON_NULL_DELAY_NS;
|
nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Check if PAPB interface is ready to receive data. Use the configuration register for this.
|
// Check if PAPB interface is ready to receive data. Use the configuration register for this.
|
||||||
|
@ -52,13 +52,14 @@ class PapbVcInterface : public VirtualChannelIF {
|
|||||||
|
|
||||||
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||||
|
|
||||||
|
enum ByteWidthCfg : uint32_t { ONE = 0b00, TWO = 0b01, THREE = 0b10, FOUR = 0b11 };
|
||||||
/**
|
/**
|
||||||
* Configuration bits:
|
* Configuration bits:
|
||||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||||
* bit[2]: Set this bit to 1 to abort a transferred packet
|
* bit[2]: Set this bit to 1 to abort a transferred packet
|
||||||
* bit[3]: Signals to VcInterface the start of a new telemetry packet
|
* bit[3]: Signals to VcInterface the start of a new telemetry packet
|
||||||
*/
|
*/
|
||||||
static constexpr uint32_t CONFIG_START = 0b00001000;
|
static constexpr uint32_t CONFIG_DATA_INPUT = 0b00001000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abort a transferred packet.
|
* Abort a transferred packet.
|
||||||
@ -78,7 +79,7 @@ class PapbVcInterface : public VirtualChannelIF {
|
|||||||
*/
|
*/
|
||||||
static const int DATA_REG_OFFSET = 256;
|
static const int DATA_REG_OFFSET = 256;
|
||||||
|
|
||||||
static constexpr long int FIRST_NON_NULL_DELAY_NS = 10;
|
static constexpr long int FIRST_DELAY_PAPB_POLLING_NS = 10;
|
||||||
static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40;
|
static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40;
|
||||||
|
|
||||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||||
@ -102,7 +103,7 @@ class PapbVcInterface : public VirtualChannelIF {
|
|||||||
* @brief This function sends the config byte to the virtual channel of the PTME IP Core
|
* @brief This function sends the config byte to the virtual channel of the PTME IP Core
|
||||||
* to initiate a packet transfer.
|
* to initiate a packet transfer.
|
||||||
*/
|
*/
|
||||||
void startPacketTransfer();
|
void startPacketTransfer(ByteWidthCfg initWidth);
|
||||||
|
|
||||||
void abortPacketTransfer();
|
void abortPacketTransfer();
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
|
|||||||
TaskFactory::delayTask(100);
|
TaskFactory::delayTask(100);
|
||||||
} else if (vcBusyDuringDump) {
|
} else if (vcBusyDuringDump) {
|
||||||
// TODO: Might not be necessary
|
// TODO: Might not be necessary
|
||||||
|
sif::debug << "VC busy, delaying" << std::endl;
|
||||||
TaskFactory::delayTask(10);
|
TaskFactory::delayTask(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
|||||||
if (not busy) {
|
if (not busy) {
|
||||||
TaskFactory::delayTask(100);
|
TaskFactory::delayTask(100);
|
||||||
} else if (dumpContext.vcBusyDuringDump) {
|
} else if (dumpContext.vcBusyDuringDump) {
|
||||||
|
sif::debug << "VC busy, delaying" << std::endl;
|
||||||
// TODO: Might not be necessary
|
// TODO: Might not be necessary
|
||||||
TaskFactory::delayTask(10);
|
TaskFactory::delayTask(10);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user