Use units in SPI

This commit is contained in:
Peter Johnson
2019-08-24 21:28:20 -07:00
parent 07ac711b31
commit 5dd0d1b7db
4 changed files with 82 additions and 11 deletions

View File

@@ -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;

View File

@@ -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<Notifier>(&PIDController::Calculate, this);
m_controlLoop->StartPeriodic(period);
m_controlLoop->StartPeriodic(units::second_t(period));
}
PIDController::~PIDController() {

View File

@@ -259,12 +259,16 @@ void SPI::SetAutoTransmitData(wpi::ArrayRef<uint8_t> 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<double>(), &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<double>(), &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();

View File

@@ -12,6 +12,7 @@
#include <memory>
#include <hal/SPITypes.h>
#include <units/units.h>
#include <wpi/ArrayRef.h>
#include <wpi/deprecated.h>
@@ -173,6 +174,16 @@ class SPI : public ErrorBase {
*/
void SetAutoTransmitData(wpi::ArrayRef<uint8_t> 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);