Browse Source

BLOCKS: Fix heap sync issue when block is reconnected

Reset lastPacketIndexReceived when a device is reconnected to mirror behaviour in firmware.
tags/2021-05-28
Mike Toon Tom Poole 6 years ago
parent
commit
efbb530d9d
2 changed files with 74 additions and 50 deletions
  1. +70
    -47
      modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h
  2. +4
    -3
      modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp

+ 70
- 47
modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h View File

@@ -19,8 +19,15 @@
==============================================================================
*/
#ifndef JUCE_DUMP_LITTLEFOOT_HEAP_STATUS
#define JUCE_DUMP_LITTLEFOOT_HEAP_STATUS 0
#endif
#define JUCE_DUMP_LITTLEFOOT_HEAP_STATUS 0
#if JUCE_DUMP_LITTLEFOOT_HEAP_STATUS
#define JUCE_LOG_LITTLEFOOT_HEAP(text) DBG(text)
#else
#define JUCE_LOG_LITTLEFOOT_HEAP(text)
#endif
namespace littlefoot
{
@@ -43,15 +50,27 @@ struct LittleFootRemoteHeap
resetDeviceStateToUnknown();
}
void clear() noexcept
void reset()
{
JUCE_LOG_LITTLEFOOT_HEAP ("Resetting heap state");
clearTargetData();
resetDeviceStateToUnknown();
lastPacketIndexReceived = 0;
}
void clearTargetData() noexcept
{
JUCE_LOG_LITTLEFOOT_HEAP ("Clearing target heap data");
zeromem (targetData, sizeof (targetData));
invalidateData();
needsSyncing = true;
programStateKnown = false;
}
void resetDeviceStateToUnknown()
{
invalidateData();
JUCE_LOG_LITTLEFOOT_HEAP ("Resetting device state to unknown");
needsSyncing = true;
programStateKnown = false;
messagesSent.clear();
resetDataRangeToUnknown (0, ImplementationClass::maxBlockSize);
}
@@ -66,20 +85,19 @@ struct LittleFootRemoteHeap
void setByte (size_t offset, uint8 value) noexcept
{
if (offset < blockSize)
if (offset >= blockSize)
{
if (targetData[offset] != value)
{
targetData[offset] = value;
needsSyncing = true;
if (programStateKnown && offset < programSize)
programStateKnown = false;
}
jassertfalse;
return;
}
else
if (targetData[offset] != value)
{
jassertfalse;
targetData[offset] = value;
needsSyncing = true;
if (offset < programSize)
programStateKnown = false;
}
}
@@ -99,8 +117,14 @@ struct LittleFootRemoteHeap
if (readLittleEndianBitsInBuffer (targetData, startBit, numBits) != value)
{
JUCE_LOG_LITTLEFOOT_HEAP ("Set bits sync " << String (startBit) << " " << String (numBits) << String (value));
writeLittleEndianBitsInBuffer (targetData, startBit, numBits, value);
invalidateData();
needsSyncing = true;
if (startBit < programSize)
programStateKnown = false;
}
}
@@ -113,12 +137,6 @@ struct LittleFootRemoteHeap
return 0;
}
void invalidateData() noexcept
{
needsSyncing = true;
programStateKnown = false;
}
bool isFullySynced() const noexcept
{
return ! needsSyncing;
@@ -167,7 +185,8 @@ struct LittleFootRemoteHeap
m->dispatchTime = Time::getCurrentTime();
bi.sendMessageToDevice (m->packet);
//DBG ("Sending packet " << (int) m->packetIndex << " - " << m->packet.size() << " bytes, device " << bi.getDeviceIndex());
JUCE_LOG_LITTLEFOOT_HEAP ("Sending packet " << (int) m->packetIndex << " - " << m->packet.size() << " bytes, device " << bi.getDeviceIndex());
if (getTotalSizeOfMessagesSent() > 200)
break;
@@ -176,43 +195,45 @@ struct LittleFootRemoteHeap
void handleACKFromDevice (ImplementationClass& bi, uint32 packetIndex) noexcept
{
//DBG ("ACK " << (int) packetIndex << " device " << (int) bi.getDeviceIndex());
if (packetIndex == lastPacketIndexReceived)
return;
if (lastPacketIndexReceived != packetIndex)
{
lastPacketIndexReceived = packetIndex;
JUCE_LOG_LITTLEFOOT_HEAP ("ACK " << (int) packetIndex << " device " << (int) bi.getDeviceIndex()
<< ", last packet received " << String (lastPacketIndexReceived));
for (int i = messagesSent.size(); --i >= 0;)
{
auto& m = *messagesSent.getUnchecked(i);
lastPacketIndexReceived = packetIndex;
if (m.packetIndex == packetIndex)
{
for (uint32 j = 0; j < blockSize; ++j)
deviceState[j] = m.resultDataState[j];
for (int i = messagesSent.size(); --i >= 0;)
{
auto& m = *messagesSent.getUnchecked(i);
programStateKnown = false;
messagesSent.removeRange (0, i + 1);
dumpStatus();
sendChanges (bi, false);
if (m.packetIndex == packetIndex)
{
for (uint32 j = 0; j < blockSize; ++j)
deviceState[j] = m.resultDataState[j];
if (messagesSent.isEmpty())
needsSyncing = false;
programStateKnown = false;
messagesSent.removeRange (0, i + 1);
dumpStatus();
sendChanges (bi, false);
return;
if (messagesSent.isEmpty())
{
JUCE_LOG_LITTLEFOOT_HEAP ("Heap fully synced");
needsSyncing = false;
}
}
resetDeviceStateToUnknown();
return;
}
}
resetDeviceStateToUnknown();
}
bool isProgramLoaded() noexcept
{
if (! programStateKnown)
{
programStateKnown = true;
uint8 deviceMemory[ImplementationClass::maxBlockSize];
for (size_t i = 0; i < blockSize; ++i)
@@ -221,6 +242,8 @@ struct LittleFootRemoteHeap
littlefoot::Program prog (deviceMemory, (uint32) blockSize);
programLoaded = prog.checksumMatches();
programSize = prog.getProgramSize();
programStateKnown = true;
}
return programLoaded;
@@ -287,8 +310,8 @@ private:
ignoreUnused (proportionOK);
DBG ("Heap: " << areas << " " << String (roundToInt (100 * proportionOK)) << "% "
<< (isProgramLoaded() ? "Ready" : "Loading"));
JUCE_LOG_LITTLEFOOT_HEAP ("Heap: " << areas << " " << String (roundToInt (100 * proportionOK))
<< "% " << (isProgramLoaded() ? "Ready" : "Loading"));
#endif
}


+ 4
- 3
modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp View File

@@ -85,8 +85,9 @@ public:
updateDeviceInfo (deviceInfo);
remoteHeap.reset();
setProgram (nullptr);
remoteHeap.resetDeviceStateToUnknown();
if (auto surface = dynamic_cast<TouchSurfaceImplementation*> (touchSurface.get()))
surface->activateTouchSurface();
@@ -294,7 +295,7 @@ public:
if (program == nullptr)
{
remoteHeap.clear();
remoteHeap.clearTargetData();
return Result::ok();
}
@@ -316,7 +317,7 @@ public:
programSize = (uint32) size;
remoteHeap.resetDataRangeToUnknown (0, remoteHeap.blockSize);
remoteHeap.clear();
remoteHeap.clearTargetData();
remoteHeap.sendChanges (*this, true);
remoteHeap.resetDataRangeToUnknown (0, (uint32) size);


Loading…
Cancel
Save