From 5dd0d1b7db778a1f341c123da4fc8474bbdba64c Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 24 Aug 2019 21:28:20 -0700 Subject: [PATCH] Use units in SPI --- wpilibc/src/main/native/cpp/ADXRS450_Gyro.cpp | 4 +- wpilibc/src/main/native/cpp/PIDController.cpp | 2 +- wpilibc/src/main/native/cpp/SPI.cpp | 32 ++++++++--- wpilibc/src/main/native/include/frc/SPI.h | 55 +++++++++++++++++++ 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/wpilibc/src/main/native/cpp/ADXRS450_Gyro.cpp b/wpilibc/src/main/native/cpp/ADXRS450_Gyro.cpp index 875f403b64..71a350b14b 100644 --- a/wpilibc/src/main/native/cpp/ADXRS450_Gyro.cpp +++ b/wpilibc/src/main/native/cpp/ADXRS450_Gyro.cpp @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) 2015-2018 FIRST. All Rights Reserved. */ +/* Copyright (c) 2015-2019 FIRST. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ @@ -14,7 +14,7 @@ using namespace frc; -static constexpr double kSamplePeriod = 0.0005; +static constexpr auto kSamplePeriod = 0.0005_s; static constexpr double kCalibrationSampleTime = 5.0; static constexpr double kDegreePerSecondPerLSB = 0.0125; diff --git a/wpilibc/src/main/native/cpp/PIDController.cpp b/wpilibc/src/main/native/cpp/PIDController.cpp index 2e50360926..0c86f55c48 100644 --- a/wpilibc/src/main/native/cpp/PIDController.cpp +++ b/wpilibc/src/main/native/cpp/PIDController.cpp @@ -31,7 +31,7 @@ PIDController::PIDController(double Kp, double Ki, double Kd, double Kf, double period) : PIDBase(Kp, Ki, Kd, Kf, source, output) { m_controlLoop = std::make_unique(&PIDController::Calculate, this); - m_controlLoop->StartPeriodic(period); + m_controlLoop->StartPeriodic(units::second_t(period)); } PIDController::~PIDController() { diff --git a/wpilibc/src/main/native/cpp/SPI.cpp b/wpilibc/src/main/native/cpp/SPI.cpp index a884c3b964..54cf82b196 100644 --- a/wpilibc/src/main/native/cpp/SPI.cpp +++ b/wpilibc/src/main/native/cpp/SPI.cpp @@ -259,12 +259,16 @@ void SPI::SetAutoTransmitData(wpi::ArrayRef dataToSend, int zeroSize) { wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } -void SPI::StartAutoRate(double period) { +void SPI::StartAutoRate(units::second_t period) { int32_t status = 0; - HAL_StartSPIAutoRate(m_port, period, &status); + HAL_StartSPIAutoRate(m_port, period.to(), &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } +void SPI::StartAutoRate(double period) { + StartAutoRate(units::second_t(period)); +} + void SPI::StartAutoTrigger(DigitalSource& source, bool rising, bool falling) { int32_t status = 0; HAL_StartSPIAutoTrigger( @@ -286,14 +290,19 @@ void SPI::ForceAutoRead() { wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); } -int SPI::ReadAutoReceivedData(uint32_t* buffer, int numToRead, double timeout) { +int SPI::ReadAutoReceivedData(uint32_t* buffer, int numToRead, + units::second_t timeout) { int32_t status = 0; - int32_t val = - HAL_ReadSPIAutoReceivedData(m_port, buffer, numToRead, timeout, &status); + int32_t val = HAL_ReadSPIAutoReceivedData(m_port, buffer, numToRead, + timeout.to(), &status); wpi_setErrorWithContext(status, HAL_GetErrorMessage(status)); return val; } +int SPI::ReadAutoReceivedData(uint32_t* buffer, int numToRead, double timeout) { + return ReadAutoReceivedData(buffer, numToRead, units::second_t(timeout)); +} + int SPI::GetAutoDroppedCount() { int32_t status = 0; int32_t val = HAL_GetSPIAutoDroppedCount(m_port, &status); @@ -301,9 +310,9 @@ int SPI::GetAutoDroppedCount() { return val; } -void SPI::InitAccumulator(double period, int cmd, int xferSize, int validMask, - int validValue, int dataShift, int dataSize, - bool isSigned, bool bigEndian) { +void SPI::InitAccumulator(units::second_t period, int cmd, int xferSize, + int validMask, int validValue, int dataShift, + int dataSize, bool isSigned, bool bigEndian) { InitAuto(xferSize * kAccumulateDepth); uint8_t cmdBytes[4] = {0, 0, 0, 0}; if (bigEndian) { @@ -328,6 +337,13 @@ void SPI::InitAccumulator(double period, int cmd, int xferSize, int validMask, m_accum->m_notifier.StartPeriodic(period * kAccumulateDepth / 2); } +void SPI::InitAccumulator(double period, int cmd, int xferSize, int validMask, + int validValue, int dataShift, int dataSize, + bool isSigned, bool bigEndian) { + InitAccumulator(units::second_t(period), cmd, xferSize, validMask, validValue, + dataShift, dataSize, isSigned, bigEndian); +} + void SPI::FreeAccumulator() { m_accum.reset(nullptr); FreeAuto(); diff --git a/wpilibc/src/main/native/include/frc/SPI.h b/wpilibc/src/main/native/include/frc/SPI.h index a5e6a44c9c..fb4835e941 100644 --- a/wpilibc/src/main/native/include/frc/SPI.h +++ b/wpilibc/src/main/native/include/frc/SPI.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -173,6 +174,16 @@ class SPI : public ErrorBase { */ void SetAutoTransmitData(wpi::ArrayRef dataToSend, int zeroSize); + /** + * Start running the automatic SPI transfer engine at a periodic rate. + * + * InitAuto() and SetAutoTransmitData() must be called before calling this + * function. + * + * @param period period between transfers (us resolution) + */ + void StartAutoRate(units::second_t period); + /** * Start running the automatic SPI transfer engine at a periodic rate. * @@ -181,6 +192,7 @@ class SPI : public ErrorBase { * * @param period period between transfers, in seconds (us resolution) */ + WPI_DEPRECATED("Use StartAutoRate with unit-safety instead") void StartAutoRate(double period); /** @@ -205,6 +217,28 @@ class SPI : public ErrorBase { */ void ForceAutoRead(); + /** + * Read data that has been transferred by the automatic SPI transfer engine. + * + * Transfers may be made a byte at a time, so it's necessary for the caller + * to handle cases where an entire transfer has not been completed. + * + * 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 + * size of the data and zeroSize set in SetAutoTransmitData(). + * + * Blocks until numToRead words have been read or timeout expires. + * May be called with numToRead=0 to retrieve how many words are available. + * + * @param buffer buffer where read words are stored + * @param numToRead number of words to read + * @param timeout timeout (ms resolution) + * @return Number of words remaining to be read + */ + int ReadAutoReceivedData(uint32_t* buffer, int numToRead, + units::second_t timeout); + /** * Read data that has been transferred by the automatic SPI transfer engine. * @@ -224,6 +258,7 @@ class SPI : public ErrorBase { * @param timeout timeout in seconds (ms resolution) * @return Number of words remaining to be read */ + WPI_DEPRECATED("Use ReadAutoReceivedData with unit-safety instead") int ReadAutoReceivedData(uint32_t* buffer, int numToRead, double timeout); /** @@ -249,6 +284,26 @@ class SPI : public ErrorBase { * @param isSigned Is data field signed? * @param bigEndian Is device big endian? */ + void InitAccumulator(units::second_t period, int cmd, int xferSize, + int validMask, int validValue, int dataShift, + int dataSize, bool isSigned, bool bigEndian); + + /** + * Initialize the accumulator. + * + * @param period Time between reads + * @param cmd SPI command to send to request data + * @param xferSize SPI transfer size, in bytes + * @param validMask Mask to apply to received data for validity checking + * @param validData After valid_mask is applied, required matching value for + * validity checking + * @param dataShift Bit shift to apply to received data to get actual data + * value + * @param dataSize Size (in bits) of data field + * @param isSigned Is data field signed? + * @param bigEndian Is device big endian? + */ + WPI_DEPRECATED("Use InitAccumulator with unit-safety instead") void InitAccumulator(double period, int cmd, int xferSize, int validMask, int validValue, int dataShift, int dataSize, bool isSigned, bool bigEndian);