mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-13 10:29:35 +01:00
[sam] Implementation of SPI multibyte transfer
This commit is contained in:
parent
5f88564b2b
commit
6a5b82f062
@ -196,6 +196,58 @@ byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
|
||||
return d & 0xFF;
|
||||
}
|
||||
|
||||
void SPIClass::transfer(byte _pin, void *_buf, size_t _count, SPITransferMode _mode) {
|
||||
if (_count == 0)
|
||||
return;
|
||||
|
||||
uint8_t *buffer = (uint8_t *)_buf;
|
||||
if (_count == 1) {
|
||||
*buffer = transfer(_pin, *buffer, _mode);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
||||
bool reverse = (bitOrder[ch] == LSBFIRST);
|
||||
|
||||
// Send the first byte
|
||||
uint32_t d = *buffer;
|
||||
if (reverse)
|
||||
d = __REV(__RBIT(d));
|
||||
while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
|
||||
;
|
||||
spi->SPI_TDR = d | SPI_PCS(ch);
|
||||
|
||||
while (_count > 1) {
|
||||
// Prepare next byte
|
||||
d = *(buffer+1);
|
||||
if (reverse)
|
||||
d = __REV(__RBIT(d));
|
||||
if (_count == 2 && _mode == SPI_LAST)
|
||||
d |= SPI_TDR_LASTXFER;
|
||||
|
||||
// Read transferred byte and send next one straight away
|
||||
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
||||
;
|
||||
uint8_t r = spi->SPI_RDR;
|
||||
spi->SPI_TDR = d | SPI_PCS(ch);
|
||||
|
||||
// Save read byte
|
||||
if (reverse)
|
||||
r = __REV(__RBIT(r));
|
||||
*buffer = r;
|
||||
buffer++;
|
||||
_count--;
|
||||
}
|
||||
|
||||
// Receive the last transferred byte
|
||||
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
||||
;
|
||||
uint8_t r = spi->SPI_RDR;
|
||||
if (reverse)
|
||||
r = __REV(__RBIT(r));
|
||||
*buffer = r;
|
||||
}
|
||||
|
||||
void SPIClass::attachInterrupt(void) {
|
||||
// Should be enableInterrupt()
|
||||
}
|
||||
|
@ -80,8 +80,12 @@ class SPIClass {
|
||||
public:
|
||||
SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void));
|
||||
|
||||
// Transfer functions
|
||||
byte transfer(byte _pin, uint8_t _data, SPITransferMode _mode = SPI_LAST);
|
||||
void transfer(byte _pin, void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST);
|
||||
// Transfer functions on default pin BOARD_SPI_DEFAULT_SS
|
||||
byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); }
|
||||
byte transfer(byte _channel, uint8_t _data, SPITransferMode _mode = SPI_LAST);
|
||||
void transfer(void *_buf, size_t _count, SPITransferMode _mode = SPI_LAST) { transfer(BOARD_SPI_DEFAULT_SS, _buf, _count, _mode); }
|
||||
|
||||
// Transaction Functions
|
||||
void usingInterrupt(uint8_t interruptNumber);
|
||||
|
Loading…
x
Reference in New Issue
Block a user