Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions libraries/SPI/src/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,97 @@ void SPIClass::transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, S
}
}

/**
* @brief Transfer multiple copies of the same byte on the SPI bus.
* begin() or beginTransaction() must be called at least once before.
* @param _pin: CS pin to select a device (optional). If the previous transfer
* used another CS pin then the SPI instance will be reconfigured.
* @param data: byte to send.
* @param count: number of times to send byte.
* @param _mode: (optional) can be SPI_CONTINUE in case of multiple successive
* send or SPI_LAST to indicate the end of send.
* If the _mode is set to SPI_CONTINUE, keep the SPI instance alive.
* That means the CS pin is not reset. Be careful in case you use
* several CS pin.
*/
void SPIClass::transfer(uint8_t _pin, uint8_t data, size_t count, SPITransferMode _mode)
{
uint8_t rx_buffer = 0;

uint8_t idx = pinIdx(_pin, GET_IDX);
if (idx >= NB_SPI_SETTINGS) {
return;
}

if (_pin != _CSPinConfig) {
spi_init(&_spi, spiSettings[idx].clk,
spiSettings[idx].dMode,
spiSettings[idx].bOrder);
_CSPinConfig = _pin;
}

if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_spi.pin_ssel == NC)) {
digitalWrite(_pin, LOW);
}

for(size_t c = 0; c < count; c++) {
spi_transfer(&_spi, &data, &rx_buffer, sizeof(uint8_t), SPI_TRANSFER_TIMEOUT, true);
}

if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) {
digitalWrite(_pin, HIGH);
}
}

/**
* @brief Transfer two bytes on the SPI bus in 16 bits format multiple times
* begin() or beginTransaction() must be called at least once before.
* @param _pin: CS pin to select a device (optional). If the previous transfer
* used another CS pin then the SPI instance will be reconfigured.
* @param data: bytes to send.
* @param count: number of times to send data.
* @param _mode: (optional) can be SPI_CONTINUE in case of multiple successive
* send or SPI_LAST to indicate the end of send.
* If the _mode is set to SPI_CONTINUE, keep the SPI instance alive.
* That means the CS pin is not reset. Be careful in case you use
* several CS pin.
*/
void SPIClass::transfer16(uint8_t _pin, uint16_t data, size_t count, SPITransferMode _mode)
{
uint16_t rx_buffer = 0;
uint16_t tmp;

uint8_t idx = pinIdx(_pin, GET_IDX);
if (idx >= NB_SPI_SETTINGS) {
return;
}

if (_pin != _CSPinConfig) {
spi_init(&_spi, spiSettings[idx].clk,
spiSettings[idx].dMode,
spiSettings[idx].bOrder);
_CSPinConfig = _pin;
}

if (spiSettings[idx].bOrder) {
tmp = ((data & 0xff00) >> 8) | ((data & 0xff) << 8);
data = tmp;
}

if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_spi.pin_ssel == NC)) {
digitalWrite(_pin, LOW);
}

for(size_t c=0; c<count; c++) {
spi_transfer(&_spi, (uint8_t *)&data, (uint8_t *)&rx_buffer, sizeof(uint16_t),
SPI_TRANSFER_TIMEOUT, true);
}

if ((_pin != CS_PIN_CONTROLLED_BY_USER) && (_mode == SPI_LAST) && (_spi.pin_ssel == NC)) {
digitalWrite(_pin, HIGH);
}
}

/**
* @brief Not implemented.
*/
Expand Down
12 changes: 12 additions & 0 deletions libraries/SPI/src/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ class SPIClass {
uint16_t transfer16(uint8_t pin, uint16_t _data, SPITransferMode _mode = SPI_LAST);
void transfer(uint8_t pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
void transfer(byte _pin, void *_bufout, void *_bufin, size_t _count, SPITransferMode _mode = SPI_LAST);
void transfer(uint8_t pin, uint8_t _data, size_t count, SPITransferMode _mode = SPI_LAST);
void transfer16(uint8_t pin, uint16_t _data, size_t count, SPITransferMode _mode = SPI_LAST);

// Transfer functions when user controls himself the CS pin.
byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST)
Expand All @@ -201,6 +203,16 @@ class SPIClass {
transfer(CS_PIN_CONTROLLED_BY_USER, _bufout, _bufin, _count, _mode);
}

void transfer(uint8_t _data, size_t count, SPITransferMode _mode = SPI_LAST)
{
transfer(CS_PIN_CONTROLLED_BY_USER, _data, count, _mode);
}

void transfer16(uint16_t _data, size_t count, SPITransferMode _mode = SPI_LAST)
{
transfer16(CS_PIN_CONTROLLED_BY_USER, _data, count, _mode);
}

/* These methods are deprecated and kept for compatibility.
* Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
*/
Expand Down