Update auto SPI for timestamp changes (#1457)

The 2019 FPGA image switched the output of auto SPI from plain bytes to a
sequence of 32-bit words (timestamp, then words with the byte values in the
least significant byte of each word).

In addition to changing the HAL and simulators to reflect this, add piecewise
integration support to wpilibc/wpilibj SPI to take advantage of the timestamps
and use it in the ADXRS450 gyro.
This commit is contained in:
Peter Johnson
2018-12-06 22:29:20 -08:00
committed by GitHub
parent 7e1ec28839
commit dcbf02a1ec
19 changed files with 271 additions and 88 deletions

View File

@@ -604,7 +604,7 @@ void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status) {
spiSystem->strobeAutoForceOne(status);
}
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint8_t* buffer,
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint32_t* buffer,
int32_t numToRead, double timeout,
int32_t* status) {
std::lock_guard<wpi::mutex> lock(spiAutoMutex);

View File

@@ -436,8 +436,8 @@ Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__ILjava_nio_ByteBuffer_2ID
SPIJNI_LOG(logDEBUG) << "Port = " << port;
SPIJNI_LOG(logDEBUG) << "NumToRead = " << numToRead;
SPIJNI_LOG(logDEBUG) << "Timeout = " << timeout;
uint8_t* recvBuf =
reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
uint32_t* recvBuf =
reinterpret_cast<uint32_t*>(env->GetDirectBufferAddress(buffer));
int32_t status = 0;
jint retval = HAL_ReadSPIAutoReceivedData(
static_cast<HAL_SPIPort>(port), recvBuf, numToRead, timeout, &status);
@@ -450,18 +450,18 @@ Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__ILjava_nio_ByteBuffer_2ID
/*
* Class: edu_wpi_first_hal_SPIJNI
* Method: spiReadAutoReceivedData
* Signature: (I[BID)I
* Signature: (I[IID)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__I_3BID
(JNIEnv* env, jclass, jint port, jbyteArray buffer, jint numToRead,
Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__I_3IID
(JNIEnv* env, jclass, jint port, jintArray buffer, jint numToRead,
jdouble timeout)
{
SPIJNI_LOG(logDEBUG) << "Calling SPIJNI spiReadAutoReceivedData";
SPIJNI_LOG(logDEBUG) << "Port = " << port;
SPIJNI_LOG(logDEBUG) << "NumToRead = " << numToRead;
SPIJNI_LOG(logDEBUG) << "Timeout = " << timeout;
wpi::SmallVector<uint8_t, 128> recvBuf;
wpi::SmallVector<uint32_t, 128> recvBuf;
recvBuf.resize(numToRead);
int32_t status = 0;
jint retval =
@@ -471,8 +471,8 @@ Java_edu_wpi_first_hal_SPIJNI_spiReadAutoReceivedData__I_3BID
SPIJNI_LOG(logDEBUG) << "Return = " << retval;
if (!CheckStatus(env, status)) return retval;
if (numToRead > 0) {
env->SetByteArrayRegion(buffer, 0, numToRead,
reinterpret_cast<const jbyte*>(recvBuf.data()));
env->SetIntArrayRegion(buffer, 0, numToRead,
reinterpret_cast<const jint*>(recvBuf.data()));
}
return retval;
}

View File

@@ -218,16 +218,20 @@ void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status);
/**
* Reads data received by the SPI accumulator.
* Reads data received by the SPI accumulator. Each received data sequence
* consists of a timestamp followed by the received data bytes, one byte per
* word (in the least significant byte). The length of each received data
* sequence is the same as the combined dataSize + zeroSize set in
* HAL_SetSPIAutoTransmitData.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4
* for MXP.
* @param buffer The buffer to store the data into.
* @param numToRead The number of bytes to read.
* @param numToRead The number of words to read.
* @param timeout The read timeout (in seconds).
* @return The number of bytes actually read.
* @return The number of words actually read.
*/
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint8_t* buffer,
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint32_t* buffer,
int32_t numToRead, double timeout,
int32_t* status);

View File

@@ -14,7 +14,7 @@
typedef void (*HAL_SpiReadAutoReceiveBufferCallback)(const char* name,
void* param,
unsigned char* buffer,
uint32_t* buffer,
int32_t numToRead,
int32_t* outputCount);

View File

@@ -54,7 +54,7 @@ void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t dataSize, int32_t zeroSize,
int32_t* status) {}
void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status) {}
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint8_t* buffer,
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint32_t* buffer,
int32_t numToRead, double timeout,
int32_t* status) {
return SimSPIData[port].ReadAutoReceivedData(buffer, numToRead, timeout,

View File

@@ -69,7 +69,7 @@ jint SimOnLoad(JavaVM* vm, void* reserved) {
spiReadAutoReceiveBufferCallbackCallback =
env->GetMethodID(spiReadAutoReceiveBufferCallbackCls, "callback",
"(Ljava/lang/String;[BI)I");
"(Ljava/lang/String;[II)I");
if (!spiReadAutoReceiveBufferCallbackCallback) return JNI_ERR;
InitializeStore();

View File

@@ -39,7 +39,7 @@ void SpiReadAutoReceiveBufferCallbackStore::create(JNIEnv* env, jobject obj) {
}
int32_t SpiReadAutoReceiveBufferCallbackStore::performCallback(
const char* name, unsigned char* buffer, int32_t numToRead) {
const char* name, uint32_t* buffer, int32_t numToRead) {
JNIEnv* env;
JavaVM* vm = sim::GetJVM();
bool didAttachThread = false;
@@ -58,15 +58,14 @@ int32_t SpiReadAutoReceiveBufferCallbackStore::performCallback(
wpi::outs().flush();
}
auto toCallbackArr =
MakeJByteArray(env, wpi::StringRef{reinterpret_cast<const char*>(buffer),
static_cast<size_t>(numToRead)});
auto toCallbackArr = MakeJIntArray(
env, wpi::ArrayRef<uint32_t>{buffer, static_cast<size_t>(numToRead)});
jint ret = env->CallIntMethod(m_call, sim::GetBufferCallback(),
MakeJString(env, name), toCallbackArr,
(jint)numToRead);
jbyte* fromCallbackArr = reinterpret_cast<jbyte*>(
jint* fromCallbackArr = reinterpret_cast<jint*>(
env->GetPrimitiveArrayCritical(toCallbackArr, nullptr));
for (int i = 0; i < ret; i++) {
@@ -106,7 +105,7 @@ SIM_JniHandle sim::AllocateSpiBufferCallback(
callbackStore->create(env, callback);
auto callbackFunc = [](const char* name, void* param, unsigned char* buffer,
auto callbackFunc = [](const char* name, void* param, uint32_t* buffer,
int32_t numToRead, int32_t* outputCount) {
uintptr_t handleTmp = reinterpret_cast<uintptr_t>(param);
SIM_JniHandle handle = static_cast<SIM_JniHandle>(handleTmp);

View File

@@ -22,7 +22,7 @@ namespace sim {
class SpiReadAutoReceiveBufferCallbackStore {
public:
void create(JNIEnv* env, jobject obj);
int32_t performCallback(const char* name, unsigned char* buffer,
int32_t performCallback(const char* name, uint32_t* buffer,
int32_t numToRead);
void free(JNIEnv* env);
void setCallbackId(int32_t id) { callbackId = id; }

View File

@@ -46,7 +46,7 @@ int32_t SPIData::Transaction(const uint8_t* dataToSend, uint8_t* dataReceived,
return size;
}
int32_t SPIData::ReadAutoReceivedData(uint8_t* buffer, int32_t numToRead,
int32_t SPIData::ReadAutoReceivedData(uint32_t* buffer, int32_t numToRead,
double timeout, int32_t* status) {
int32_t outputCount = 0;
autoReceivedData(buffer, numToRead, &outputCount);

View File

@@ -24,7 +24,7 @@ class SPIData {
int32_t Write(const uint8_t* dataToSend, int32_t sendSize);
int32_t Transaction(const uint8_t* dataToSend, uint8_t* dataReceived,
int32_t size);
int32_t ReadAutoReceivedData(uint8_t* buffer, int32_t numToRead,
int32_t ReadAutoReceivedData(uint32_t* buffer, int32_t numToRead,
double timeout, int32_t* status);
SimDataValue<HAL_Bool, MakeBoolean, GetInitializedName> initialized{false};