mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-26 01:51:41 +00:00
[hal,wpilib] Fix SPI Mode Setting (#4434)
SPI Mode setting was very broken. MSB and LSB sets did not work (MSB is the only one supported) and if LSB was set (which was the default) the ioct to set clock phase would fail. This deprecates all the individual functions, the LSB/MSB functions, and adds an SPI mode selection function. This is usually more understandable, and shows up in a lot more documentation
This commit is contained in:
@@ -364,19 +364,27 @@ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
|
||||
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||
}
|
||||
|
||||
void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
|
||||
HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {
|
||||
void HAL_SetSPIMode(HAL_SPIPort port, HAL_SPIMode mode) {
|
||||
if (port < 0 || port >= kSpiMaxHandles) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t mode = 0;
|
||||
mode |= (!msbFirst ? 8 : 0);
|
||||
mode |= (clkIdleHigh ? 2 : 0);
|
||||
mode |= (sampleOnTrailing ? 1 : 0);
|
||||
uint8_t mode8 = mode & SPI_MODE_3;
|
||||
|
||||
std::scoped_lock lock(spiApiMutexes[port]);
|
||||
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
|
||||
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode8);
|
||||
}
|
||||
|
||||
HAL_SPIMode HAL_GetSPIMode(HAL_SPIPort port) {
|
||||
if (port < 0 || port >= kSpiMaxHandles) {
|
||||
return HAL_SPI_kMode0;
|
||||
}
|
||||
|
||||
uint8_t mode8 = 0;
|
||||
|
||||
std::scoped_lock lock(spiApiMutexes[port]);
|
||||
ioctl(HAL_GetSPIHandle(port), SPI_IOC_RD_MODE, &mode8);
|
||||
return static_cast<HAL_SPIMode>(mode8 & SPI_MODE_3);
|
||||
}
|
||||
|
||||
void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
|
||||
|
||||
@@ -15,6 +15,27 @@
|
||||
using namespace hal;
|
||||
using namespace wpi::java;
|
||||
|
||||
static_assert(HAL_SPIPort::HAL_SPI_kInvalid ==
|
||||
edu_wpi_first_hal_SPIJNI_INVALID_PORT);
|
||||
static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS0 ==
|
||||
edu_wpi_first_hal_SPIJNI_ONBOARD_CS0_PORT);
|
||||
static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS1 ==
|
||||
edu_wpi_first_hal_SPIJNI_ONBOARD_CS1_PORT);
|
||||
static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS2 ==
|
||||
edu_wpi_first_hal_SPIJNI_ONBOARD_CS2_PORT);
|
||||
static_assert(HAL_SPIPort::HAL_SPI_kOnboardCS3 ==
|
||||
edu_wpi_first_hal_SPIJNI_ONBOARD_CS3_PORT);
|
||||
static_assert(HAL_SPIPort::HAL_SPI_kMXP == edu_wpi_first_hal_SPIJNI_MXP_PORT);
|
||||
|
||||
static_assert(HAL_SPIMode::HAL_SPI_kMode0 ==
|
||||
edu_wpi_first_hal_SPIJNI_SPI_MODE0);
|
||||
static_assert(HAL_SPIMode::HAL_SPI_kMode1 ==
|
||||
edu_wpi_first_hal_SPIJNI_SPI_MODE1);
|
||||
static_assert(HAL_SPIMode::HAL_SPI_kMode2 ==
|
||||
edu_wpi_first_hal_SPIJNI_SPI_MODE2);
|
||||
static_assert(HAL_SPIMode::HAL_SPI_kMode3 ==
|
||||
edu_wpi_first_hal_SPIJNI_SPI_MODE3);
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
@@ -202,16 +223,27 @@ Java_edu_wpi_first_hal_SPIJNI_spiSetSpeed
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_SPIJNI
|
||||
* Method: spiSetOpts
|
||||
* Signature: (IIII)V
|
||||
* Method: spiSetMode
|
||||
* Signature: (II)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_SPIJNI_spiSetOpts
|
||||
(JNIEnv*, jclass, jint port, jint msb_first, jint sample_on_trailing,
|
||||
jint clk_idle_high)
|
||||
Java_edu_wpi_first_hal_SPIJNI_spiSetMode
|
||||
(JNIEnv*, jclass, jint port, jint mode)
|
||||
{
|
||||
HAL_SetSPIOpts(static_cast<HAL_SPIPort>(port), msb_first, sample_on_trailing,
|
||||
clk_idle_high);
|
||||
HAL_SetSPIMode(static_cast<HAL_SPIPort>(port),
|
||||
static_cast<HAL_SPIMode>(mode));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_SPIJNI
|
||||
* Method: spiGetMode
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_SPIJNI_spiGetMode
|
||||
(JNIEnv*, jclass, jint port)
|
||||
{
|
||||
return static_cast<jint>(HAL_GetSPIMode(static_cast<HAL_SPIPort>(port)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -90,23 +90,27 @@ void HAL_CloseSPI(HAL_SPIPort port);
|
||||
*
|
||||
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
|
||||
* MXP
|
||||
* @param speed The speed in Hz (0-1MHz)
|
||||
* @param speed The speed in Hz (500KHz-10MHz)
|
||||
*/
|
||||
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed);
|
||||
|
||||
/**
|
||||
* Sets the SPI options.
|
||||
* Sets the SPI Mode.
|
||||
*
|
||||
* @param port The number of the port to use. 0-3 for Onboard
|
||||
* CS0-CS2, 4 for MXP
|
||||
* @param msbFirst True to write the MSB first, False for LSB first
|
||||
* @param sampleOnTrailing True to sample on the trailing edge, False to sample
|
||||
* on the leading edge
|
||||
* @param clkIdleHigh True to set the clock to active low, False to set the
|
||||
* clock active high
|
||||
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
|
||||
* MXP
|
||||
* @param mode The SPI mode to use
|
||||
*/
|
||||
void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
|
||||
HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh);
|
||||
void HAL_SetSPIMode(HAL_SPIPort port, HAL_SPIMode mode);
|
||||
|
||||
/**
|
||||
* Gets the SPI Mode.
|
||||
*
|
||||
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
|
||||
* MXP
|
||||
* @returns The SPI mode currently set
|
||||
*/
|
||||
HAL_SPIMode HAL_GetSPIMode(HAL_SPIPort port);
|
||||
|
||||
/**
|
||||
* Sets the CS Active high for a SPI port.
|
||||
|
||||
@@ -25,6 +25,15 @@ HAL_ENUM(HAL_SPIPort) {
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// clang-format off
|
||||
HAL_ENUM(HAL_SPIMode) {
|
||||
HAL_SPI_kMode0 = 0,
|
||||
HAL_SPI_kMode1 = 1,
|
||||
HAL_SPI_kMode2 = 2,
|
||||
HAL_SPI_kMode3 = 3,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace hal {
|
||||
|
||||
|
||||
@@ -34,8 +34,10 @@ void HAL_CloseSPI(HAL_SPIPort port) {
|
||||
SimSPIData[port].initialized = false;
|
||||
}
|
||||
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {}
|
||||
void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
|
||||
HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {}
|
||||
void HAL_SetSPIMode(HAL_SPIPort port, HAL_SPIMode mode) {}
|
||||
HAL_SPIMode HAL_GetSPIMode(HAL_SPIPort port) {
|
||||
return HAL_SPI_kMode0;
|
||||
}
|
||||
void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {}
|
||||
void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {}
|
||||
int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
|
||||
|
||||
Reference in New Issue
Block a user