Skip to content

Commit

Permalink
chore(SPI): align with ArduinoCoreAPI
Browse files Browse the repository at this point in the history
Signed-off-by: Frederic Pillon <[email protected]>
  • Loading branch information
fpistm committed Nov 9, 2023
1 parent 0637f1f commit 1ae6110
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 92 deletions.
94 changes: 49 additions & 45 deletions libraries/SPI/src/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ SPIClass::SPIClass(uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t ssel)
void SPIClass::begin(void)
{
_spi.handle.State = HAL_SPI_STATE_RESET;
spi_init(&_spi, _spiSettings.clk,
_spiSettings.dMode,
_spiSettings.bOrder);
spi_init(&_spi, _spiSettings.getClockFreq(),
_spiSettings.getDataMode(),
_spiSettings.getBitOrder());
}

/**
Expand All @@ -69,14 +69,12 @@ void SPIClass::begin(void)
*/
void SPIClass::beginTransaction(SPISettings settings)
{
_spiSettings.clk = settings.clk;
_spiSettings.dMode = settings.dMode;
_spiSettings.bOrder = settings.bOrder;
_spiSettings.noReceive = settings.noReceive;

spi_init(&_spi, _spiSettings.clk,
_spiSettings.dMode,
_spiSettings.bOrder);
if (_spiSettings != settings) {
_spiSettings = settings;
spi_init(&_spi, _spiSettings.getClockFreq(),
_spiSettings.getDataMode(),
_spiSettings.getBitOrder());
}
}

/**
Expand All @@ -102,39 +100,37 @@ void SPIClass::end()
*/
void SPIClass::setBitOrder(BitOrder bitOrder)
{
_spiSettings.bOrder = bitOrder;
_spiSettings.setBitOrder(bitOrder);

spi_init(&_spi, _spiSettings.clk,
_spiSettings.dMode,
_spiSettings.bOrder);
spi_init(&_spi, _spiSettings.getClockFreq(),
_spiSettings.getDataMode(),
_spiSettings.getBitOrder());
}

/**
* @brief Deprecated function.
* Configure the data mode (clock polarity and clock phase)
* @param _mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
* @param mode: SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3
* @note
* Mode Clock Polarity (CPOL) Clock Phase (CPHA)
* SPI_MODE0 0 0
* SPI_MODE1 0 1
* SPI_MODE2 1 0
* SPI_MODE3 1 1
*/
void SPIClass::setDataMode(uint8_t _mode)

void SPIClass::setDataMode(uint8_t mode)
{
if (SPI_MODE0 == _mode) {
_spiSettings.dMode = SPI_MODE_0;
} else if (SPI_MODE1 == _mode) {
_spiSettings.dMode = SPI_MODE_1;
} else if (SPI_MODE2 == _mode) {
_spiSettings.dMode = SPI_MODE_2;
} else if (SPI_MODE3 == _mode) {
_spiSettings.dMode = SPI_MODE_3;
}
setDataMode((SPIMode)mode);
}

spi_init(&_spi, _spiSettings.clk,
_spiSettings.dMode,
_spiSettings.bOrder);
void SPIClass::setDataMode(SPIMode mode)
{
_spiSettings.setDataMode(mode);

spi_init(&_spi, _spiSettings.getClockFreq(),
_spiSettings.getDataMode(),
_spiSettings.getBitOrder());
}

/**
Expand All @@ -146,15 +142,15 @@ void SPIClass::setDataMode(uint8_t _mode)
void SPIClass::setClockDivider(uint8_t _divider)
{
if (_divider == 0) {
_spiSettings.clk = SPI_SPEED_CLOCK_DEFAULT;
_spiSettings.setClockFreq(SPI_SPEED_CLOCK_DEFAULT);
} else {
/* Get clk freq of the SPI instance and compute it */
_spiSettings.clk = spi_getClkFreq(&_spi) / _divider;
/* Get clock freq of the SPI instance and compute it */
_spiSettings.setClockFreq(spi_getClkFreq(&_spi) / _divider);
}

spi_init(&_spi, _spiSettings.clk,
_spiSettings.dMode,
_spiSettings.bOrder);
spi_init(&_spi, _spiSettings.getClockFreq(),
_spiSettings.getDataMode(),
_spiSettings.getBitOrder());
}

/**
Expand All @@ -163,9 +159,9 @@ void SPIClass::setClockDivider(uint8_t _divider)
* @param data: byte to send.
* @return byte received from the slave.
*/
byte SPIClass::transfer(uint8_t data)
uint8_t SPIClass::transfer(uint8_t data)
{
spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive);
spi_transfer(&_spi, &data, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv());
return data;
}

Expand All @@ -179,14 +175,14 @@ uint16_t SPIClass::transfer16(uint16_t data)
{
uint16_t tmp;

if (_spiSettings.bOrder) {
if (_spiSettings.getBitOrder()) {
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
data = tmp;
}
spi_transfer(&_spi, (uint8_t *)&data, sizeof(uint16_t),
SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive);
SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv());

if (_spiSettings.bOrder) {
if (_spiSettings.getBitOrder()) {
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
data = tmp;
}
Expand All @@ -197,22 +193,30 @@ uint16_t SPIClass::transfer16(uint16_t data)
/**
* @brief Transfer several bytes. Only one buffer used to send and receive data.
* begin() or beginTransaction() must be called at least once before.
* @param _buf: pointer to the bytes to send. The bytes received are copy in
* @param buf: pointer to the bytes to send. The bytes received are copy in
* this buffer.
* @param _count: number of bytes to send/receive.
* @param count: number of bytes to send/receive.
*/
void SPIClass::transfer(void *_buf, size_t _count)
void SPIClass::transfer(void *buf, size_t count)
{
if ((count != 0) && (buf != NULL)) {
spi_transfer(&_spi, ((uint8_t *)buf), count,
SPI_TRANSFER_TIMEOUT, _spiSettings.noReceive);
SPI_TRANSFER_TIMEOUT, _spiSettings.getSkipRecv());
}
}

/**
* @brief Not implemented.
*/
void SPIClass::usingInterrupt(uint8_t interruptNumber)
void SPIClass::usingInterrupt(int interruptNumber)
{
UNUSED(interruptNumber);
}

/**
* @brief Not implemented.
*/
void SPIClass::notUsingInterrupt(int interruptNumber)
{
UNUSED(interruptNumber);
}
Expand Down
140 changes: 102 additions & 38 deletions libraries/SPI/src/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ extern "C" {
#define SPI_CLOCK_DIV64 64
#define SPI_CLOCK_DIV128 128

// SPI mode parameters for SPISettings
#define SPI_MODE0 0x00
#define SPI_MODE1 0x01
#define SPI_MODE2 0x02
#define SPI_MODE3 0x03

#define SPI_TRANSMITRECEIVE 0x0
#define SPI_TRANSMITONLY 0x1

Expand All @@ -54,37 +48,105 @@ extern "C" {

class SPISettings {
public:
constexpr SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, bool noRecv = SPI_TRANSMITRECEIVE)
: clk(clock),
bOrder(bitOrder),
dMode((spi_mode_e)(
(SPI_MODE0 == dataMode) ? SPI_MODE_0 :
(SPI_MODE1 == dataMode) ? SPI_MODE_1 :
(SPI_MODE2 == dataMode) ? SPI_MODE_2 :
(SPI_MODE3 == dataMode) ? SPI_MODE_3 :
SPI_MODE0
)),
noReceive(noRecv)
{ }
constexpr SPISettings()
: clk(SPI_SPEED_CLOCK_DEFAULT),
bOrder(MSBFIRST),
dMode(SPI_MODE_0),
noReceive(SPI_TRANSMITRECEIVE)
{ }
SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv = SPI_TRANSMITRECEIVE)
{
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode, skipRecv);
} else {
init_MightInline(clock, bitOrder, dataMode, skipRecv);
}
}

SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode, bool skipRecv = SPI_TRANSMITRECEIVE)
{
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, (SPIMode)dataMode, skipRecv);
} else {
init_MightInline(clock, bitOrder, (SPIMode)dataMode, skipRecv);
}
}

// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
SPISettings()
{
init_AlwaysInline(SPI_SPEED_CLOCK_DEFAULT, MSBFIRST, SPI_MODE0, SPI_TRANSMITRECEIVE);
}

bool operator==(const SPISettings &rhs) const
{
if ((this->clockFreq == rhs.clockFreq) &&
(this->bitOrder == rhs.bitOrder) &&
(this->dataMode == rhs.dataMode) &&
(this->skipRecv == rhs.skipRecv)) {
return true;
}
return false;
}

bool operator!=(const SPISettings &rhs) const
{
return !(*this == rhs);
}

uint32_t getClockFreq() const
{
return clockFreq;
}
SPIMode getDataMode() const
{
return dataMode;
}
BitOrder getBitOrder() const
{
return (bitOrder);
}
bool getSkipRecv() const
{
return skipRecv;
}

void setClockFreq(uint32_t clkFreq)
{
clockFreq = clkFreq;
}
void setDataMode(SPIMode mode)
{
dataMode = mode;
}
void setBitOrder(BitOrder order)
{
bitOrder = order;
}
void setSkipRecv(bool skip)
{
skipRecv = skip;
}

private:
uint32_t clk; //specifies the spi bus maximum clock speed
BitOrder bOrder; //bit order (MSBFirst or LSBFirst)
spi_mode_e dMode; //one of the data mode
//Mode Clock Polarity (CPOL) Clock Phase (CPHA)
//SPI_MODE0 0 0
//SPI_MODE1 0 1
//SPI_MODE2 1 0
//SPI_MODE3 1 1
friend class SPIClass;
bool noReceive;
void init_MightInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv)
{
init_AlwaysInline(clock, bitOrder, dataMode, skipRecv);
}

// Core developer MUST use an helper function in beginTransaction() to use this data
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode, bool skipRecv) __attribute__((__always_inline__))
{
this->clockFreq = clock;
this->dataMode = dataMode;
this->bitOrder = bitOrder;
this->skipRecv = skipRecv;
}

uint32_t clockFreq;
SPIMode dataMode;
BitOrder bitOrder;
bool skipRecv;

friend class HardwareSPI;
};

const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();

class SPIClass {
public:
SPIClass();
Expand Down Expand Up @@ -137,19 +199,21 @@ class SPIClass {
/* Transfer functions: must be called after initialization of the SPI
* instance with begin() or beginTransaction().
*/
virtual byte transfer(uint8_t _data);
virtual uint8_t transfer(uint8_t _data);
virtual uint16_t transfer16(uint16_t _data);
virtual void transfer(void *_buf, size_t _count);
virtual void transfer(void *buf, size_t count);

/* These methods are deprecated and kept for compatibility.
* Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
*/
void setBitOrder(BitOrder);
void setDataMode(uint8_t);
void setDataMode(SPIMode);
void setClockDivider(uint8_t);

// Not implemented functions. Kept for backward compatibility.
void usingInterrupt(uint8_t interruptNumber);
// Not implemented functions. Kept for compatibility.
void usingInterrupt(int interruptNumber);
void notUsingInterrupt(int interruptNumber);
void attachInterrupt(void);
void detachInterrupt(void);

Expand Down
6 changes: 3 additions & 3 deletions libraries/SPI/src/utility/spi_com.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ static uint32_t compute_disable_delay(spi_t *obj)
* @param msb : set to 1 in msb first
* @retval None
*/
void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)
void spi_init(spi_t *obj, uint32_t speed, SPIMode mode, uint8_t msb)
{
if (obj == NULL) {
return;
Expand Down Expand Up @@ -313,13 +313,13 @@ void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb)

handle->Init.Direction = SPI_DIRECTION_2LINES;

if ((mode == SPI_MODE_0) || (mode == SPI_MODE_2)) {
if ((mode == SPI_MODE0) || (mode == SPI_MODE2)) {
handle->Init.CLKPhase = SPI_PHASE_1EDGE;
} else {
handle->Init.CLKPhase = SPI_PHASE_2EDGE;
}

if ((mode == SPI_MODE_0) || (mode == SPI_MODE_1)) {
if ((mode == SPI_MODE0) || (mode == SPI_MODE1)) {
handle->Init.CLKPolarity = SPI_POLARITY_LOW;
} else {
handle->Init.CLKPolarity = SPI_POLARITY_HIGH;
Expand Down
Loading

0 comments on commit 1ae6110

Please sign in to comment.