1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#ifndef __INC_FASTSPI_ARDUNIO_CORE_H
#define __INC_FASTSPI_ARDUNIO_CORE_H
FASTLED_NAMESPACE_BEGIN
#if defined(ARDUNIO_CORE_SPI)
#include <SPI.h>
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_RATE, SPIClass & _SPIObject>
class ArdunioCoreSPIOutput {
public:
ArdunioCoreSPIOutput() {}
// set the object representing the selectable -- ignore for now
void setSelect(Selectable *pSelect) { /* TODO */ }
// initialize the SPI subssytem
void init() { _SPIObject.begin(); }
// latch the CS select
void inline select() __attribute__((always_inline)) {
// begin the SPI transaction
_SPIObject.beginTransaction(SPISettings(_SPI_CLOCK_RATE, MSBFIRST, SPI_MODE0));
}
// release the CS select
void inline release() __attribute__((always_inline)) {
_SPIObject.endTransaction();
}
// wait until all queued up data has been written
static void waitFully() { /* TODO */ }
// write a byte out via SPI (returns immediately on writing register) -
void inline writeByte(uint8_t b) __attribute__((always_inline)) {
_SPIObject.transfer(b);
}
// write a word out via SPI (returns immediately on writing register)
void inline writeWord(uint16_t w) __attribute__((always_inline)) {
_SPIObject.transfer16(w);
}
// A raw set of writing byte values, assumes setup/init/waiting done elsewhere
static void writeBytesValueRaw(uint8_t value, int len) {
while(len--) { _SPIObject.transfer(value); }
}
// A full cycle of writing a value for len bytes, including select, release, and waiting
void writeBytesValue(uint8_t value, int len) {
select(); writeBytesValueRaw(value, len); release();
}
// A full cycle of writing a value for len bytes, including select, release, and waiting
template <class D> void writeBytes(register uint8_t *data, int len) {
uint8_t *end = data + len;
select();
// could be optimized to write 16bit words out instead of 8bit bytes
while(data != end) {
writeByte(D::adjust(*data++));
}
D::postBlock(len);
waitFully();
release();
}
// A full cycle of writing a value for len bytes, including select, release, and waiting
void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
// write a single bit out, which bit from the passed in byte is determined by template parameter
template <uint8_t BIT> inline void writeBit(uint8_t b) {
// todo
}
// write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
// parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
select();
int len = pixels.mLen;
while(pixels.has(1)) {
if(FLAGS & FLAG_START_BIT) {
writeBit<0>(1);
}
writeByte(D::adjust(pixels.loadAndScale0()));
writeByte(D::adjust(pixels.loadAndScale1()));
writeByte(D::adjust(pixels.loadAndScale2()));
pixels.advanceData();
pixels.stepDithering();
}
D::postBlock(len);
release();
}
};
#endif
FASTLED_NAMESPACE_END
#endif
|