24 #error Pixels_SPIhw.h must be included before Pixels_<CONTROLLER>.h
27 #ifndef PIXELS_SPIHW_H
28 #define PIXELS_SPIHW_H
30 #define SPI_CLOCK_DIV4 0x00
31 #define SPI_CLOCK_DIV16 0x01
32 #define SPI_CLOCK_DIV64 0x02
33 #define SPI_CLOCK_DIV128 0x03
34 #define SPI_CLOCK_DIV2 0x04
35 #define SPI_CLOCK_DIV8 0x05
36 #define SPI_CLOCK_DIV32 0x06
37 #define SPI_CLOCK_DIV64 0x07
39 #define SPI_MODE0 0x00
40 #define SPI_MODE1 0x04
41 #define SPI_MODE2 0x08
42 #define SPI_MODE3 0x0C
44 #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
45 #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
46 #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
48 #define SPI(X) SPDR=X;while(!(SPSR&_BV(SPIF)))
72 digitalWrite(pinRST,LOW);
74 digitalWrite(pinRST,HIGH);
78 void writeCmd(uint8_t b);
79 __attribute__((noinline))
void writeData(uint8_t data);
81 void writeData(uint8_t hi, uint8_t lo) {
86 void writeDataTwice(uint8_t b) {
91 void writeCmdData(uint8_t cmd, uint16_t data) {
93 writeData(highByte(data));
94 writeData(lowByte(data));
98 void setSPIBitOrder(uint8_t bitOrder);
99 void setSPIDataMode(uint8_t mode);
100 void setSPIClockDivider(uint8_t rate);
113 inline void setSpiPins(uint8_t scl, uint8_t sda, uint8_t cs, uint8_t rst, uint8_t wr = 255) {
119 eightBit = wr != 255;
126 inline void setPpiPins(uint8_t rs, uint8_t wr, uint8_t cs, uint8_t rst, uint8_t rd) {
129 inline void registerSelect() {
132 void initInterface();
135 void SPIhw::initInterface() {
136 registerSCL = portOutputRegister(digitalPinToPort(pinSCL));
137 bitmaskSCL = digitalPinToBitMask(pinSCL);
138 registerSDA = portOutputRegister(digitalPinToPort(pinSDA));
139 bitmaskSDA = digitalPinToBitMask(pinSDA);
140 registerWR = portOutputRegister(digitalPinToPort(pinWR));
141 bitmaskWR = digitalPinToBitMask(pinWR);
142 registerCS = portOutputRegister(digitalPinToPort(pinCS));
143 bitmaskCS = digitalPinToBitMask(pinCS);
145 pinMode(pinSCL,OUTPUT);
146 pinMode(pinSDA,OUTPUT);
147 pinMode(pinWR,OUTPUT);
148 pinMode(pinRST,OUTPUT);
149 pinMode(pinCS,OUTPUT);
153 setSPIBitOrder(MSBFIRST);
154 setSPIDataMode(SPI_MODE3);
159 void SPIhw::writeCmd(uint8_t cmd) {
161 *registerWR &= ~bitmaskWR;
164 cbi(registerSDA, bitmaskSDA);
165 cbi(registerSCL, bitmaskSCL);
167 sbi(registerSCL, bitmaskSCL);
171 #if defined(TEENSYDUINO)
172 SPI0_SR = SPI_SR_TCF;
174 while (!(SPI0_SR & SPI_SR_TCF)) ;
177 while (!(SPSR & _BV(SPIF)));
181 void SPIhw::writeData(uint8_t data) {
183 *registerWR |= bitmaskWR;
186 sbi(registerSDA, bitmaskSDA);
187 cbi(registerSCL, bitmaskSCL);
189 sbi(registerSCL, bitmaskSCL);
193 #if defined(TEENSYDUINO)
194 SPI0_SR = SPI_SR_TCF;
196 while (!(SPI0_SR & SPI_SR_TCF)) ;
199 while (!(SPSR & _BV(SPIF)));
203 void SPIhw::beginSPI() {
204 cbi(registerSCL, bitmaskSCL);
205 cbi(registerSDA, bitmaskSDA);
206 digitalWrite(pinCS, HIGH);
215 #if defined(TEENSYDUINO)
216 uint32_t ctar = SPI_CTAR_FMSZ(7) |
217 SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_DBR;
219 SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
221 SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
222 SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
224 DDRB = DDRB | B00000001;
225 PORTB = PORTB | B00000001;
229 void SPIhw::endSPI() {
233 void SPIhw::setSPIBitOrder(uint8_t bitOrder) {
234 if(bitOrder == LSBFIRST) {
237 SPCR &= ~(_BV(DORD));
241 void SPIhw::setSPIDataMode(uint8_t mode) {
242 SPCR = (SPCR & ~SPI_MODE_MASK) | mode;
245 void SPIhw::setSPIClockDivider(uint8_t rate) {
246 SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
247 SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
void setSpiPins(uint8_t scl, uint8_t sda, uint8_t cs, uint8_t rst, uint8_t wr=255)
void setPpiPins(uint8_t rs, uint8_t wr, uint8_t cs, uint8_t rst, uint8_t rd)