Skip to content

Commit

Permalink
added protected template to replace std::array<>, chunked transfer fo…
Browse files Browse the repository at this point in the history
…r AVR

The AVR arduino platform doesn't have std::array. To use the chunked
transfer mode, I added a template to replace it. It has roughly the same
semantics as std::array<> and is protected to Adafruit_SPIDevice.

With this template, the chunked transfer is also possible for 8bit AVRs.
  • Loading branch information
eringerli committed May 14, 2022
1 parent 059c87e commit f08f376
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 50 deletions.
52 changes: 2 additions & 50 deletions Adafruit_SPIDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
#if !defined(SPI_INTERFACES_COUNT) || \
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))

//! constant for the buffer size for the chunked transfer
constexpr size_t maxBufferSizeForChunkedTransfer = 64;

//#define DEBUG_SERIAL Serial

#ifdef DEBUG_SERIAL
#if !defined(__AVR__)
template <typename T>
static void printChunk(const char *title, const T &buffer, const uint8_t size,
const uint16_t chunkNumber) {
Expand All @@ -32,7 +28,6 @@ static void printChunk(const char *title, const T &buffer, const uint8_t size,
}
DEBUG_SERIAL.println();
}
#endif

static void printBuffer(const char *title, const uint8_t *buffer,
const size_t len) {
Expand Down Expand Up @@ -370,8 +365,7 @@ void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,
const uint8_t *prefix_buffer,
size_t prefix_len) {
#if !defined(__AVR__)
std::array<uint8_t, maxBufferSizeForChunkedTransfer> chunkBuffer;
Array<uint8_t, maxBufferSizeForChunkedTransfer> chunkBuffer;

auto chunkBufferIterator = chunkBuffer.begin();

Expand Down Expand Up @@ -421,26 +415,6 @@ bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,

endTransactionWithDeassertingCS();

#else // !defined(__AVR__)

beginTransactionWithAssertingCS();

for (size_t i = 0; i < prefix_len; i++) {
transfer(prefix_buffer[i]);
}
for (size_t i = 0; i < len; i++) {
transfer(buffer[i]);
}

endTransactionWithDeassertingCS();

#ifdef DEBUG_SERIAL
printBuffer("write() prefix_buffer", prefix_buffer, prefix_len);
printBuffer("write() buffer", buffer, len);
#endif

#endif // !defined(__AVR__)

return true;
}

Expand Down Expand Up @@ -484,8 +458,7 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer,
size_t write_len, uint8_t *read_buffer,
size_t read_len, uint8_t sendvalue) {
#if !defined(__AVR__)
std::array<uint8_t, maxBufferSizeForChunkedTransfer> chunkBuffer;
Array<uint8_t, maxBufferSizeForChunkedTransfer> chunkBuffer;

auto chunkBufferIterator = chunkBuffer.begin();

Expand Down Expand Up @@ -570,27 +543,6 @@ bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer,

endTransactionWithDeassertingCS();

#else // !defined(__AVR__)

beginTransactionWithAssertingCS();

for (size_t i = 0; i < write_len; i++) {
transfer(write_buffer[i]);
}

for (size_t i = 0; i < read_len; i++) {
read_buffer[i] = transfer(sendvalue);
}

endTransactionWithDeassertingCS();

#ifdef DEBUG_SERIAL
printBuffer("write_then_read() write_buffer", write_buffer, write_len);
printBuffer("write_then_read() read_buffer", read_buffer, read_len);
#endif

#endif // !defined(__AVR__)

return true;
}

Expand Down
57 changes: 57 additions & 0 deletions Adafruit_SPIDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,71 @@ class Adafruit_SPIDevice {
uint32_t _freq;
BusIOBitOrder _dataOrder;
uint8_t _dataMode;

void setChipSelect(int value);

int8_t _cs, _sck, _mosi, _miso;
#ifdef BUSIO_USE_FAST_PINIO
BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
#endif

//! constant for the buffer size for the chunked transfer
static constexpr size_t maxBufferSizeForChunkedTransfer =
#ifdef __AVR__
32;
#else
64;
#endif
bool _begun;

protected:
/*!
* @brief Template to encypsulate a C-array, provides STL-style accessors
* analoguous to std::array<>
* @param Type the type of the array
* @param Size the size of the array
*/
template <typename Type, size_t Size> class Array {
public:
/*! @brief returns a pointer the start of the buffer
* @returns a pointer the start of the buffer
*/
Type *begin() { return buffer; }

/*! @brief returns a pointer the one increment beyond the end of the buffer
* @returns a pointer the one increment beyond the end of the buffer
*/
Type *end() { return endPointer; }

/*! @brief returns the size of the buffer
* @returns the size of the buffer
*/
constexpr size_t size() { return Size; }

/*! @brief returns the buffer
* @returns the buffer
*/
Type *data() { return buffer; }

/*! @brief returns a reference to the element at @param i
* @param i the index
* @returns a reference to the element at @param i
*/
Type &operator[](size_t i) { return buffer[i]; }

/*! @brief returns a reference to the element at @param i
* @param i the index
* @returns a reference to the element at @param i
*/
const Type &operator[](size_t i) const { return buffer[i]; }

private:
//! the buffer
Type buffer[Size];
//! address buffer one increment after the end
Type *endPointer = buffer + Size;
};
};

#endif // has SPI defined
Expand Down

0 comments on commit f08f376

Please sign in to comment.