Skip to content

Commit f08f376

Browse files
committed
added protected template to replace std::array<>, chunked transfer for 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.
1 parent 059c87e commit f08f376

File tree

2 files changed

+59
-50
lines changed

2 files changed

+59
-50
lines changed

Adafruit_SPIDevice.cpp

+2-50
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@
77
#if !defined(SPI_INTERFACES_COUNT) || \
88
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
99

10-
//! constant for the buffer size for the chunked transfer
11-
constexpr size_t maxBufferSizeForChunkedTransfer = 64;
12-
1310
//#define DEBUG_SERIAL Serial
1411

1512
#ifdef DEBUG_SERIAL
16-
#if !defined(__AVR__)
1713
template <typename T>
1814
static void printChunk(const char *title, const T &buffer, const uint8_t size,
1915
const uint16_t chunkNumber) {
@@ -32,7 +28,6 @@ static void printChunk(const char *title, const T &buffer, const uint8_t size,
3228
}
3329
DEBUG_SERIAL.println();
3430
}
35-
#endif
3631

3732
static void printBuffer(const char *title, const uint8_t *buffer,
3833
const size_t len) {
@@ -370,8 +365,7 @@ void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
370365
bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,
371366
const uint8_t *prefix_buffer,
372367
size_t prefix_len) {
373-
#if !defined(__AVR__)
374-
std::array<uint8_t, maxBufferSizeForChunkedTransfer> chunkBuffer;
368+
Array<uint8_t, maxBufferSizeForChunkedTransfer> chunkBuffer;
375369

376370
auto chunkBufferIterator = chunkBuffer.begin();
377371

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

422416
endTransactionWithDeassertingCS();
423417

424-
#else // !defined(__AVR__)
425-
426-
beginTransactionWithAssertingCS();
427-
428-
for (size_t i = 0; i < prefix_len; i++) {
429-
transfer(prefix_buffer[i]);
430-
}
431-
for (size_t i = 0; i < len; i++) {
432-
transfer(buffer[i]);
433-
}
434-
435-
endTransactionWithDeassertingCS();
436-
437-
#ifdef DEBUG_SERIAL
438-
printBuffer("write() prefix_buffer", prefix_buffer, prefix_len);
439-
printBuffer("write() buffer", buffer, len);
440-
#endif
441-
442-
#endif // !defined(__AVR__)
443-
444418
return true;
445419
}
446420

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

490463
auto chunkBufferIterator = chunkBuffer.begin();
491464

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

571544
endTransactionWithDeassertingCS();
572545

573-
#else // !defined(__AVR__)
574-
575-
beginTransactionWithAssertingCS();
576-
577-
for (size_t i = 0; i < write_len; i++) {
578-
transfer(write_buffer[i]);
579-
}
580-
581-
for (size_t i = 0; i < read_len; i++) {
582-
read_buffer[i] = transfer(sendvalue);
583-
}
584-
585-
endTransactionWithDeassertingCS();
586-
587-
#ifdef DEBUG_SERIAL
588-
printBuffer("write_then_read() write_buffer", write_buffer, write_len);
589-
printBuffer("write_then_read() read_buffer", read_buffer, read_len);
590-
#endif
591-
592-
#endif // !defined(__AVR__)
593-
594546
return true;
595547
}
596548

Adafruit_SPIDevice.h

+57
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,71 @@ class Adafruit_SPIDevice {
109109
uint32_t _freq;
110110
BusIOBitOrder _dataOrder;
111111
uint8_t _dataMode;
112+
112113
void setChipSelect(int value);
113114

114115
int8_t _cs, _sck, _mosi, _miso;
115116
#ifdef BUSIO_USE_FAST_PINIO
116117
BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
117118
BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
118119
#endif
120+
121+
//! constant for the buffer size for the chunked transfer
122+
static constexpr size_t maxBufferSizeForChunkedTransfer =
123+
#ifdef __AVR__
124+
32;
125+
#else
126+
64;
127+
#endif
119128
bool _begun;
129+
130+
protected:
131+
/*!
132+
* @brief Template to encypsulate a C-array, provides STL-style accessors
133+
* analoguous to std::array<>
134+
* @param Type the type of the array
135+
* @param Size the size of the array
136+
*/
137+
template <typename Type, size_t Size> class Array {
138+
public:
139+
/*! @brief returns a pointer the start of the buffer
140+
* @returns a pointer the start of the buffer
141+
*/
142+
Type *begin() { return buffer; }
143+
144+
/*! @brief returns a pointer the one increment beyond the end of the buffer
145+
* @returns a pointer the one increment beyond the end of the buffer
146+
*/
147+
Type *end() { return endPointer; }
148+
149+
/*! @brief returns the size of the buffer
150+
* @returns the size of the buffer
151+
*/
152+
constexpr size_t size() { return Size; }
153+
154+
/*! @brief returns the buffer
155+
* @returns the buffer
156+
*/
157+
Type *data() { return buffer; }
158+
159+
/*! @brief returns a reference to the element at @param i
160+
* @param i the index
161+
* @returns a reference to the element at @param i
162+
*/
163+
Type &operator[](size_t i) { return buffer[i]; }
164+
165+
/*! @brief returns a reference to the element at @param i
166+
* @param i the index
167+
* @returns a reference to the element at @param i
168+
*/
169+
const Type &operator[](size_t i) const { return buffer[i]; }
170+
171+
private:
172+
//! the buffer
173+
Type buffer[Size];
174+
//! address buffer one increment after the end
175+
Type *endPointer = buffer + Size;
176+
};
120177
};
121178

122179
#endif // has SPI defined

0 commit comments

Comments
 (0)