multi byte write support but does not work..
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

This commit is contained in:
Robin Müller 2023-03-30 13:36:44 +02:00
parent 770fee0097
commit 27370fcd44
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
2 changed files with 47 additions and 6 deletions

View File

@ -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"
@ -28,11 +29,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 (pollPapbBusySignal(0) == returnvalue::OK) { if (pollPapbBusySignal(0) == 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 too often can mess up the scheduler. // Polling the GPIO too often can mess up the scheduler.
@ -40,6 +76,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
// FPGA module which can accept packets and then takes care of dumping that packet into // FPGA module which can accept packets and then takes care of dumping that packet into
// the PTME. DMA would be an ideal solution for this. // the PTME. DMA would be an ideal solution for this.
nanosleep(&BETWEEN_POLL_DELAY, &remDelay); nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
if (pollPapbBusySignal(2) == returnvalue::OK) { if (pollPapbBusySignal(2) == returnvalue::OK) {
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]); *(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
} else { } else {
@ -57,7 +94,9 @@ 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; }
@ -65,7 +104,7 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries) const
gpio::Levels papbBusyState = gpio::Levels::LOW; gpio::Levels papbBusyState = gpio::Levels::LOW;
ReturnValue_t result; ReturnValue_t result;
uint32_t busyIdx = 0; uint32_t busyIdx = 0;
nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS; nextDelay.tv_nsec = 0;
while (true) { while (true) {
/** Check if PAPB interface is ready to receive data */ /** Check if PAPB interface is ready to receive data */

View File

@ -50,13 +50,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.
@ -88,11 +89,12 @@ class PapbVcInterface : public VirtualChannelIF {
std::string uioFile; std::string uioFile;
int mapNum = 0; int mapNum = 0;
volatile uint32_t dummy = 0;
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0}; mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 2}; const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 2};
mutable struct timespec remDelay; mutable struct timespec remDelay;
volatile uint32_t* vcBaseReg = nullptr; uint32_t* vcBaseReg = nullptr;
uint32_t vcOffset = 0; uint32_t vcOffset = 0;
@ -100,7 +102,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();