mirror of
https://github.com/preble/libpinproc
synced 2026-02-24 18:25:23 +01:00
Implement ganged writes to improve USB utilization
This commit is contained in:
@@ -115,6 +115,7 @@ PRResult PRDevice::Reset(uint32_t resetFlags)
|
|||||||
unrequestedDataQueue.empty();
|
unrequestedDataQueue.empty();
|
||||||
requestedDataQueue.empty();
|
requestedDataQueue.empty();
|
||||||
num_collected_bytes = 0;
|
num_collected_bytes = 0;
|
||||||
|
numPreparedWriteWords = 0;
|
||||||
|
|
||||||
// TODO: Assign defaults based on machineType. Some may have already been done above.
|
// TODO: Assign defaults based on machineType. Some may have already been done above.
|
||||||
return kPRSuccess;
|
return kPRSuccess;
|
||||||
@@ -159,7 +160,7 @@ PRResult PRDevice::DriverUpdateGlobalConfig(PRDriverGlobalConfig *driverGlobalCo
|
|||||||
|
|
||||||
DEBUG(PRLog("Driver Global words: %x %x\n", burst[0], burst[1]));
|
DEBUG(PRLog("Driver Global words: %x %x\n", burst[0], burst[1]));
|
||||||
DEBUG(PRLog("Watchdog words: %x %x\n", burst[2], burst[3]));
|
DEBUG(PRLog("Watchdog words: %x %x\n", burst[2], burst[3]));
|
||||||
return WriteData(burst, burstWords);
|
return PrepareWriteData(burst, burstWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRResult PRDevice::DriverGetGroupConfig(uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig)
|
PRResult PRDevice::DriverGetGroupConfig(uint8_t groupNum, PRDriverGroupConfig *driverGroupConfig)
|
||||||
@@ -179,7 +180,7 @@ PRResult PRDevice::DriverUpdateGroupConfig(PRDriverGroupConfig *driverGroupConfi
|
|||||||
rc = CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig);
|
rc = CreateDriverUpdateGroupConfigBurst(burst, driverGroupConfig);
|
||||||
|
|
||||||
DEBUG(PRLog("Words: %x %x\n", burst[0], burst[1]));
|
DEBUG(PRLog("Words: %x %x\n", burst[0], burst[1]));
|
||||||
return WriteData(burst, burstWords);
|
return PrepareWriteData(burst, burstWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRResult PRDevice::DriverGetState(uint8_t driverNum, PRDriverState *driverState)
|
PRResult PRDevice::DriverGetState(uint8_t driverNum, PRDriverState *driverState)
|
||||||
@@ -207,7 +208,7 @@ PRResult PRDevice::DriverUpdateState(PRDriverState *driverState)
|
|||||||
rc = CreateDriverUpdateBurst(burst, &drivers[driverState->driverNum]);
|
rc = CreateDriverUpdateBurst(burst, &drivers[driverState->driverNum]);
|
||||||
DEBUG(PRLog("Words: %x %x %x\n", burst[0], burst[1], burst[2]));
|
DEBUG(PRLog("Words: %x %x %x\n", burst[0], burst[1], burst[2]));
|
||||||
|
|
||||||
return WriteData(burst, burstWords);
|
return PrepareWriteData(burst, burstWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -221,7 +222,7 @@ PRResult PRDevice::DriverWatchdogTickle()
|
|||||||
driverGlobalConfig.watchdogEnable,
|
driverGlobalConfig.watchdogEnable,
|
||||||
driverGlobalConfig.watchdogResetTime);
|
driverGlobalConfig.watchdogResetTime);
|
||||||
|
|
||||||
return WriteData(burst, burstWords);
|
return PrepareWriteData(burst, burstWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -243,7 +244,7 @@ PRResult PRDevice::SwitchUpdateConfig(PRSwitchConfig *switchConfig)
|
|||||||
DEBUG(PRLog("Configuring Switch Logic"));
|
DEBUG(PRLog("Configuring Switch Logic"));
|
||||||
DEBUG(PRLog("Words: %x %x\n",burst[0],burst[1]));
|
DEBUG(PRLog("Words: %x %x\n",burst[0],burst[1]));
|
||||||
|
|
||||||
rc = WriteData(burst, burstWords);
|
rc = PrepareWriteData(burst, burstWords);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +315,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR
|
|||||||
|
|
||||||
DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3]));
|
DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3]));
|
||||||
// Write the rule:
|
// Write the rule:
|
||||||
res = WriteData(burst, burstSize);
|
res = PrepareWriteData(burst, burstSize);
|
||||||
if (res != kPRSuccess)
|
if (res != kPRSuccess)
|
||||||
{
|
{
|
||||||
DEBUG(PRLog("Error while writing switch update, attempting to revert switch rule to a safe state..."));
|
DEBUG(PRLog("Error while writing switch update, attempting to revert switch rule to a safe state..."));
|
||||||
@@ -322,7 +323,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR
|
|||||||
newRule->changeOutput = false;
|
newRule->changeOutput = false;
|
||||||
newRule->linkActive = false;
|
newRule->linkActive = false;
|
||||||
CreateSwitchUpdateRulesBurst(burst, newRule);
|
CreateSwitchUpdateRulesBurst(burst, newRule);
|
||||||
if (WriteData(burst, burstSize) == kPRSuccess)
|
if (PrepareWriteData(burst, burstSize) == kPRSuccess)
|
||||||
DEBUG(PRLog("Disabled successfully.\n"));
|
DEBUG(PRLog("Disabled successfully.\n"));
|
||||||
else
|
else
|
||||||
DEBUG(PRLog("Failed to disable.\n"));
|
DEBUG(PRLog("Failed to disable.\n"));
|
||||||
@@ -339,7 +340,7 @@ PRResult PRDevice::SwitchUpdateRule(uint8_t switchNum, PREventType eventType, PR
|
|||||||
DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3]));
|
DEBUG(PRLog("Rule Words: %x %x %x %x\n", burst[0],burst[1],burst[2],burst[3]));
|
||||||
|
|
||||||
// Write the rule:
|
// Write the rule:
|
||||||
res = WriteData(burst, burstSize);
|
res = PrepareWriteData(burst, burstSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -358,7 +359,7 @@ int32_t PRDevice::DMDUpdateConfig(PRDMDConfig *dmdConfig)
|
|||||||
DEBUG(PRLog("Words: %x %x %x %x %x %x %x\n",burst[0],burst[1],burst[2],burst[3],
|
DEBUG(PRLog("Words: %x %x %x %x %x %x %x\n",burst[0],burst[1],burst[2],burst[3],
|
||||||
burst[4],burst[5],burst[6]));
|
burst[4],burst[5],burst[6]));
|
||||||
|
|
||||||
rc = WriteData(burst, burstWords);
|
rc = PrepareWriteData(burst, burstWords);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +380,7 @@ PRResult PRDevice::DMDDraw(uint8_t * dots)
|
|||||||
dmd_command_buffer[k+1] = p_dmd_frame_buffer_words[k];
|
dmd_command_buffer[k+1] = p_dmd_frame_buffer_words[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteData(dmd_command_buffer, words_per_frame+1);
|
return PrepareWriteData(dmd_command_buffer, words_per_frame+1);
|
||||||
|
|
||||||
// The following code prints out the init lines for the 4 Xilinx BlockRAMs
|
// The following code prints out the init lines for the 4 Xilinx BlockRAMs
|
||||||
// in the FPGA. It's used to make an image for the P-ROC to display on power-up.
|
// in the FPGA. It's used to make an image for the P-ROC to display on power-up.
|
||||||
@@ -497,6 +498,36 @@ PRResult PRDevice::RequestData(uint32_t module_select, uint32_t start_addr, int3
|
|||||||
return WriteData(&requestWord, 1);
|
return WriteData(&requestWord, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRResult PRDevice::PrepareWriteData(uint32_t * words, int32_t numWords)
|
||||||
|
{
|
||||||
|
if (numWords > maxWriteWords)
|
||||||
|
{
|
||||||
|
DEBUG(PRLog("%d words Exceeds write capabilities. Restrict write requests to %d words.", numWords, maxWriteWords));
|
||||||
|
return kPRFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are already some words prepared to be written and the addition of the new
|
||||||
|
// words will be too many, flush the currently prepared words to the P-ROC now.
|
||||||
|
if (numPreparedWriteWords + numWords > maxWriteWords)
|
||||||
|
{
|
||||||
|
if (FlushWriteData() == kPRFailure);
|
||||||
|
return kPRFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(preparedWriteWords + numPreparedWriteWords, words, numWords * 4);
|
||||||
|
numPreparedWriteWords += numWords;
|
||||||
|
|
||||||
|
return kPRSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRResult PRDevice::FlushWriteData()
|
||||||
|
{
|
||||||
|
PRResult res;
|
||||||
|
res = WriteData(preparedWriteWords, numPreparedWriteWords);
|
||||||
|
numPreparedWriteWords = 0; // Reset word counter
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords)
|
PRResult PRDevice::WriteData(uint32_t * words, int32_t numWords)
|
||||||
{
|
{
|
||||||
int32_t j,k;
|
int32_t j,k;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ using namespace std;
|
|||||||
#define maxDriverGroups (26)
|
#define maxDriverGroups (26)
|
||||||
#define maxDrivers (256)
|
#define maxDrivers (256)
|
||||||
#define maxSwitchRules (256<<2) // 8 bits of switchNum indicies plus bits for debounced and state.
|
#define maxSwitchRules (256<<2) // 8 bits of switchNum indicies plus bits for debounced and state.
|
||||||
|
#define maxWriteWords (1536) // Hardware supports 2048 word bursts, but restrict to 1536 for margin.
|
||||||
|
|
||||||
class PRDevice
|
class PRDevice
|
||||||
{
|
{
|
||||||
@@ -76,6 +77,13 @@ protected:
|
|||||||
PRResult VerifyChipID();
|
PRResult VerifyChipID();
|
||||||
|
|
||||||
// Raw write and read methods
|
// Raw write and read methods
|
||||||
|
//
|
||||||
|
|
||||||
|
/** Schedules data to be written to the P-ROC. */
|
||||||
|
PRResult PrepareWriteData(uint32_t * buffer, int32_t numWords);
|
||||||
|
|
||||||
|
/** Initiates a burst write of all data scheduled to be written to the P-ROC. */
|
||||||
|
PRResult FlushWriteData();
|
||||||
|
|
||||||
/** Writes data to P-ROC.
|
/** Writes data to P-ROC.
|
||||||
* Returns #kPFailure if the number of words read does not match the number requested.
|
* Returns #kPFailure if the number of words read does not match the number requested.
|
||||||
@@ -112,6 +120,9 @@ protected:
|
|||||||
queue<uint32_t> unrequestedDataQueue; /**< Queue of words received from the device that were not requested via RequestData(). Usually switch events. */
|
queue<uint32_t> unrequestedDataQueue; /**< Queue of words received from the device that were not requested via RequestData(). Usually switch events. */
|
||||||
queue<uint32_t> requestedDataQueue; /**< Queue of words received from the device as the result of a call to RequestData(). */
|
queue<uint32_t> requestedDataQueue; /**< Queue of words received from the device as the result of a call to RequestData(). */
|
||||||
|
|
||||||
|
uint32_t preparedWriteWords[maxWriteWords];
|
||||||
|
int32_t numPreparedWriteWords;
|
||||||
|
|
||||||
uint8_t collected_bytes_fifo[FTDI_BUFFER_SIZE];
|
uint8_t collected_bytes_fifo[FTDI_BUFFER_SIZE];
|
||||||
int32_t collected_bytes_rd_addr;
|
int32_t collected_bytes_rd_addr;
|
||||||
int32_t collected_bytes_wr_addr;
|
int32_t collected_bytes_wr_addr;
|
||||||
|
|||||||
Reference in New Issue
Block a user