Using the adafruit ST7735 1.8" TFT display with RFduino:
I picked up an RFduino from their Kickstarter campaign and wanted to make it work with some existing arduino parts (specifically a ST7735 display).
The RFduino has 7 GPIO lanes. I will be using the SPI interface to connect to the display.
variant.h
defines the SPI ports as follows:
#define SPI_INTERFACE NRF_SPI0
#define PIN_SPI_SS (6u)
#define PIN_SPI_MOSI (5u)
#define PIN_SPI_MISO (3u)
#define PIN_SPI_SCK (4u)
We will need to map these names to the adafruit code. The table below shows the mapping. Note that I elected to use the Arduino reset pin.
___________________________________________________________________
| adafruit name | adafruit default pin | rfduino Name | rfduino pin |
| sclk | 13 | PIN_SPI_SCK | 4 |
| mosi | 11 | PIN_SPI_MOSI | 5 |
| miso | 12 | PIN_SPI_MISO | 3 |
| cs | 10 | PIN_SPI_SS | 6 |
| CARD_CS | 4 | CARD_CS | 1 |
| dc | 9 | dc | 2 |
| rst | 8 | RESET | -1 |
___________________________________________________________________
The RFduino has a 3.3V power pin, so we use this to power the display.
Here's some closeups of the wired boards. (Excuse the shotty soldering job on the display....)
Finally we need to patch the ST7735 driver to work with the RFduino's GPIO offsets. The patch is included at the bottom of this post. The full source is attached to this page (Adafruit_ST7735_rfduino_mod.zip). The original source is on github: https://github.com/adafruit/Adafruit-ST7735-Library.
Here is a video of the finished code running. (I modified the default graphicstest program to loop.)
Patch:
diff U3 Adafruit_ST7735.cpp Adafruit_ST7735.cpp
--- Adafruit_ST7735.cpp Mon Jan 19 14:26:36 1970
+++ Adafruit_ST7735.cpp Mon Jan 19 14:26:36 1970
@@ -134,6 +134,46 @@
}
#endif //#if defined(__SAM3X8E__)
+#if defined(RFDUINO)
+inline void Adafruit_ST7735::spiwrite(uint8_t c) {
+
+// Serial.println(c, HEX);
+
+ if (hwSPI) {
+ SPI.transfer(c);
+ } else {
+ // Fast SPI bitbang swiped from LPD8806 library
+ for(uint8_t bit = 0x80; bit; bit >>= 1) {
+ if(c & bit) NRF_GPIO->OUTSET = datapinmask;
+ else NRF_GPIO->OUTCLR = datapinmask;
+ NRF_GPIO->OUTSET = clkpinmask;
+ NRF_GPIO->OUTCLR = clkpinmask;
+ }
+ }
+}
+
+void Adafruit_ST7735::writecommand(uint8_t c) {
+ NRF_GPIO->OUTCLR = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+
+// Serial.print("C ");
+ spiwrite(c);
+
+ NRF_GPIO->OUTSET = cspinmask;
+}
+
+
+void Adafruit_ST7735::writedata(uint8_t c) {
+ NRF_GPIO->OUTSET = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+
+// Serial.print("D ");
+ spiwrite(c);
+
+ NRF_GPIO->OUTSET = cspinmask;
+}
+#endif //#if defined(RFDUINO)
+
// Rather than a bazillion writecommand() and writedata() calls, screen
// initialization commands and arguments are organized in these tables
@@ -325,8 +365,12 @@
#if defined(__SAM3X8E__)
SPI.setClockDivider(21); // 4 MHz
//Due defaults to 4mHz (clock divider setting of 21), but we'll set it anyway
-#endif SPI.setBitOrder(MSBFIRST);
+#endif
+#if defined(RFDUINO)
+#else
+ SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
+#endif
} else {
pinMode(_sclk, OUTPUT);
pinMode(_sid , OUTPUT);
@@ -348,6 +392,10 @@
clkport ->PIO_CODR |= clkpinmask; // Set control bits to LOW (idle)
dataport->PIO_CODR |= datapinmask; // Signals are ACTIVE HIGH
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTCLR |= clkpinmask;
+ NRF_GPIO->OUTCLR |= datapinmask;
+#endif
}
// toggle RST low to reset; CS low so it'll listen to us
@@ -357,6 +405,9 @@
#if defined(__SAM3X8E__)
csport ->PIO_CODR |= cspinmask; // Set control bits to LOW (idle)
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTCLR |= cspinmask;
+#endif
if (_rst) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
@@ -428,7 +479,11 @@
rsport->PIO_SODR |= rspinmask;
csport->PIO_CODR |= cspinmask;
#endif
-
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+#endif
+
spiwrite(color >> 8);
spiwrite(color);
@@ -438,6 +493,9 @@
#if defined(__SAM3X8E__)
csport->PIO_SODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = cspinmask;
+#endif
}
void Adafruit_ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) {
@@ -454,7 +512,11 @@
rsport->PIO_SODR |= rspinmask;
csport->PIO_CODR |= cspinmask;
#endif
-
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+#endif
+
spiwrite(color >> 8);
spiwrite(color);
@@ -464,6 +526,9 @@
#if defined(__SAM3X8E__)
csport->PIO_SODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = cspinmask;
+#endif
}
@@ -484,16 +549,25 @@
rsport->PIO_SODR |= rspinmask;
csport->PIO_CODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+#endif
+
while (h--) {
spiwrite(hi);
spiwrite(lo);
}
+
#ifdef __AVR__
*csport |= cspinmask;
#endif
#if defined(__SAM3X8E__)
csport->PIO_SODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = cspinmask;
+#endif
}
@@ -514,6 +588,10 @@
rsport->PIO_SODR |= rspinmask;
csport->PIO_CODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+#endif
while (w--) {
spiwrite(hi);
spiwrite(lo);
@@ -524,6 +602,9 @@
#if defined(__SAM3X8E__)
csport->PIO_SODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = cspinmask;
+#endif
}
@@ -554,6 +635,11 @@
rsport->PIO_SODR |= rspinmask;
csport->PIO_CODR |= cspinmask;
#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = rspinmask;
+ NRF_GPIO->OUTCLR = cspinmask;
+#endif
+
for(y=h; y>0; y--) {
for(x=w; x>0; x--) {
spiwrite(hi);
@@ -566,6 +652,9 @@
#endif
#if defined(__SAM3X8E__)
csport->PIO_SODR |= cspinmask;
+#endif
+#if defined(RFDUINO)
+ NRF_GPIO->OUTSET = cspinmask;
#endif
}
diff U3 Adafruit_ST7735.h Adafruit_ST7735.h
--- Adafruit_ST7735.h Mon Jan 19 14:26:36 1970
+++ Adafruit_ST7735.h Mon Jan 19 14:26:36 1970
@@ -38,6 +38,13 @@
#ifdef __AVR__
#include <avr/pgmspace.h>
#endif
+#if defined(RFDUINO)
+ #define digitalPinToBitMask(P) ( 1UL << P )
+ #define PROGMEM
+ #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
+ #define pgm_read_word(addr) (*(const unsigned short *)(addr))
+ typedef unsigned char prog_uchar;
+#endif
// some flags for initR() :(
#define INITR_GREENTAB 0x0
@@ -159,6 +166,12 @@
datapinmask, clkpinmask, cspinmask, rspinmask,
colstart, rowstart; // some displays need this changed
#endif // #if defined(__SAM3X8E__)
+
+#if defined(RFDUINO)
+ uint32_t _cs, _rs, _rst, _sid, _sclk,
+ datapinmask, clkpinmask, cspinmask, rspinmask,
+ colstart, rowstart; // some displays need this changed
+#endif
}