okay, PAPB IF caches packet now

This commit is contained in:
2023-10-13 15:10:52 +02:00
parent 2279eab5e7
commit 4431883b4d
10 changed files with 80 additions and 63 deletions

View File

@ -8,8 +8,12 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId,
std::string uioFile, int mapNum)
: gpioComIF(gpioComIF), papbEmptyId(papbEmptyId), uioFile(std::move(uioFile)), mapNum(mapNum) {}
std::string uioFile, int mapNum, size_t maxPacketSize)
: gpioComIF(gpioComIF),
papbEmptyId(papbEmptyId),
packetBuf(maxPacketSize),
uioFile(std::move(uioFile)),
mapNum(mapNum) {}
PapbVcInterface::~PapbVcInterface() {}
@ -29,9 +33,17 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& w
return returnvalue::FAILED;
}
// The user must call finishWrite before starting a new packet transfer.
if (partialWriteActive) {
return INCOMPLETE_PARTIAL_WRITE;
if (writeActive) {
return IS_BUSY;
}
if (size > packetBuf.capacity()) {
sif::error << "PapbVcInterface: Packet with size " << size << " larger than maximum configured"
<< " byte size " << packetBuf.capacity() << std::endl;
return returnvalue::FAILED;
}
std::memcpy(packetBuf.data(), data, size);
currentPacketSize = size;
currentPacketIndex = 0;
if (pollReadyForPacket()) {
startPacketTransfer(ByteWidthCfg::ONE);
} else {
@ -41,14 +53,17 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& w
abortPacketTransfer();
return returnvalue::FAILED;
}
return finishWriteInternal(data, 0, size, writtenSize, false);
return advanceWrite(writtenSize);
}
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
*vcBaseReg = CONFIG_DATA_INPUT | initWidth;
}
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
void PapbVcInterface::completePacketTransfer() {
*vcBaseReg = CONFIG_END;
writeActive = false;
}
bool PapbVcInterface::pollReadyForPacket() const {
// Check if PAPB interface is ready to receive data. Use the configuration register for this.
@ -57,34 +72,20 @@ bool PapbVcInterface::pollReadyForPacket() const {
return (reg >> 6) & 0b1;
}
ReturnValue_t PapbVcInterface::finishWrite(const uint8_t* data, size_t start,
size_t remainingSize) {
ReturnValue_t PapbVcInterface::advanceWrite(size_t& writtenSize) {
if (not pollReadyForPacket()) {
return returnvalue::FAILED;
return IS_BUSY;
}
size_t dummy = 0;
return finishWriteInternal(data, start, remainingSize, dummy, true);
}
ReturnValue_t PapbVcInterface::finishWriteInternal(const uint8_t* data, size_t start,
size_t remainingSize, size_t& writtenSize,
bool abortOnPartialWrite) {
for (size_t idx = 0; idx < remainingSize; idx++) {
for (size_t idx = currentPacketIndex; idx < currentPacketSize; idx++) {
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
if (not pollReadyForPacket()) {
writtenSize = start + idx;
partialWriteActive = true;
if (abortOnPartialWrite) {
abortPacketTransfer();
partialWriteActive = false;
return returnvalue::FAILED;
}
return PARTIALLY_WRITTEN;
}
abortPacketTransfer();
return returnvalue::FAILED;
}
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[start + idx]);
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(packetBuf[currentPacketIndex]);
writtenSize++;
}
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
abortPacketTransfer();

View File

@ -6,6 +6,7 @@
#include <linux/ipcore/VirtualChannelIF.h>
#include <atomic>
#include <vector>
#include "OBSWConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
@ -30,7 +31,8 @@ class PapbVcInterface : public VirtualChannelIF {
* @param uioFile UIO file providing access to the PAPB bus
* @param mapNum Map number of UIO map associated with this virtual channel
*/
PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId, std::string uioFile, int mapNum);
PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId, std::string uioFile, int mapNum,
size_t maxPacketSize);
virtual ~PapbVcInterface();
bool isBusy() const override;
@ -42,9 +44,9 @@ class PapbVcInterface : public VirtualChannelIF {
*/
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
ReturnValue_t finishWriteInternal(const uint8_t* data, size_t start, size_t remainingSize,
size_t& writtenSize, bool abortOnPartialWrite);
ReturnValue_t advanceWrite(size_t& remainingSize) override;
// ReturnValue_t finishWriteInternal(const uint8_t* data, size_t start, size_t remainingSize,
// size_t& writtenSize, bool abortOnPartialWrite);
void cancelTransfer() override;
@ -90,9 +92,12 @@ class PapbVcInterface : public VirtualChannelIF {
/** High when external buffer memory of virtual channel is empty */
gpioId_t papbEmptyId = gpio::NO_GPIO;
std::vector<uint8_t> packetBuf;
std::string uioFile;
int mapNum = 0;
bool partialWriteActive = false;
bool writeActive = false;
size_t currentPacketIndex = 0;
size_t currentPacketSize = 0;
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10};
mutable struct timespec remDelay;