Adafruit_SPITFT.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /***************************************************
  2. This is our library for generic SPI TFT Displays with
  3. address windows and 16 bit color (e.g. ILI9341, HX8357D, ST7735...)
  4. Check out the links above for our tutorials and wiring diagrams
  5. These displays use SPI to communicate, 4 or 5 pins are required to
  6. interface (RST is optional)
  7. Adafruit invests time and resources providing this open source code,
  8. please support Adafruit and open-source hardware by purchasing
  9. products from Adafruit!
  10. Written by Limor Fried/Ladyada for Adafruit Industries.
  11. MIT license, all text above must be included in any redistribution
  12. ****************************************************/
  13. #ifndef __AVR_ATtiny85__ // NOT A CHANCE of this stuff working on ATtiny!
  14. #include "Adafruit_SPITFT.h"
  15. #ifndef ARDUINO_STM32_FEATHER
  16. #include "pins_arduino.h"
  17. #ifndef RASPI
  18. #include "wiring_private.h"
  19. #endif
  20. #endif
  21. #include <limits.h>
  22. #include "Adafruit_SPITFT_Macros.h"
  23. // Pass 8-bit (each) R,G,B, get back 16-bit packed color
  24. uint16_t Adafruit_SPITFT::color565(uint8_t r, uint8_t g, uint8_t b) {
  25. return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
  26. }
  27. Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h,
  28. int8_t cs, int8_t dc, int8_t mosi,
  29. int8_t sclk, int8_t rst, int8_t miso)
  30. : Adafruit_GFX(w, h) {
  31. _cs = cs;
  32. _dc = dc;
  33. _rst = rst;
  34. _sclk = sclk;
  35. _mosi = mosi;
  36. _miso = miso;
  37. _freq = 0;
  38. #ifdef USE_FAST_PINIO
  39. csport = portOutputRegister(digitalPinToPort(_cs));
  40. cspinmask = digitalPinToBitMask(_cs);
  41. dcport = portOutputRegister(digitalPinToPort(_dc));
  42. dcpinmask = digitalPinToBitMask(_dc);
  43. clkport = portOutputRegister(digitalPinToPort(_sclk));
  44. clkpinmask = digitalPinToBitMask(_sclk);
  45. mosiport = portOutputRegister(digitalPinToPort(_mosi));
  46. mosipinmask = digitalPinToBitMask(_mosi);
  47. if(miso >= 0){
  48. misoport = portInputRegister(digitalPinToPort(_miso));
  49. misopinmask = digitalPinToBitMask(_miso);
  50. } else {
  51. misoport = 0;
  52. misopinmask = 0;
  53. }
  54. #endif
  55. }
  56. Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h,
  57. int8_t cs, int8_t dc, int8_t rst)
  58. : Adafruit_GFX(w, h) {
  59. _cs = cs;
  60. _dc = dc;
  61. _rst = rst;
  62. _sclk = -1;
  63. _mosi = -1;
  64. _miso = -1;
  65. _freq = 0;
  66. #ifdef USE_FAST_PINIO
  67. csport = portOutputRegister(digitalPinToPort(_cs));
  68. cspinmask = digitalPinToBitMask(_cs);
  69. dcport = portOutputRegister(digitalPinToPort(_dc));
  70. dcpinmask = digitalPinToBitMask(_dc);
  71. clkport = 0;
  72. clkpinmask = 0;
  73. mosiport = 0;
  74. mosipinmask = 0;
  75. misoport = 0;
  76. misopinmask = 0;
  77. #endif
  78. }
  79. void Adafruit_SPITFT::initSPI(uint32_t freq)
  80. {
  81. _freq = freq;
  82. // Control Pins
  83. pinMode(_dc, OUTPUT);
  84. digitalWrite(_dc, LOW);
  85. pinMode(_cs, OUTPUT);
  86. digitalWrite(_cs, HIGH);
  87. // Software SPI
  88. if(_sclk >= 0){
  89. pinMode(_mosi, OUTPUT);
  90. digitalWrite(_mosi, LOW);
  91. pinMode(_sclk, OUTPUT);
  92. digitalWrite(_sclk, HIGH);
  93. if(_miso >= 0){
  94. pinMode(_miso, INPUT);
  95. }
  96. }
  97. // Hardware SPI
  98. SPI_BEGIN();
  99. // toggle RST low to reset
  100. if (_rst >= 0) {
  101. pinMode(_rst, OUTPUT);
  102. digitalWrite(_rst, HIGH);
  103. delay(100);
  104. digitalWrite(_rst, LOW);
  105. delay(100);
  106. digitalWrite(_rst, HIGH);
  107. delay(200);
  108. }
  109. }
  110. uint8_t Adafruit_SPITFT::spiRead() {
  111. if(_sclk < 0){
  112. return HSPI_READ();
  113. }
  114. if(_miso < 0){
  115. return 0;
  116. }
  117. uint8_t r = 0;
  118. for (uint8_t i=0; i<8; i++) {
  119. SSPI_SCK_LOW();
  120. SSPI_SCK_HIGH();
  121. r <<= 1;
  122. if (SSPI_MISO_READ()){
  123. r |= 0x1;
  124. }
  125. }
  126. return r;
  127. }
  128. void Adafruit_SPITFT::spiWrite(uint8_t b) {
  129. if(_sclk < 0){
  130. HSPI_WRITE(b);
  131. return;
  132. }
  133. for(uint8_t bit = 0x80; bit; bit >>= 1){
  134. if((b) & bit){
  135. SSPI_MOSI_HIGH();
  136. } else {
  137. SSPI_MOSI_LOW();
  138. }
  139. SSPI_SCK_LOW();
  140. SSPI_SCK_HIGH();
  141. }
  142. }
  143. /*
  144. * Transaction API
  145. * */
  146. void Adafruit_SPITFT::startWrite(void){
  147. SPI_BEGIN_TRANSACTION();
  148. SPI_CS_LOW();
  149. }
  150. void Adafruit_SPITFT::endWrite(void){
  151. SPI_CS_HIGH();
  152. SPI_END_TRANSACTION();
  153. }
  154. void Adafruit_SPITFT::writeCommand(uint8_t cmd){
  155. SPI_DC_LOW();
  156. spiWrite(cmd);
  157. SPI_DC_HIGH();
  158. }
  159. void Adafruit_SPITFT::pushColor(uint16_t color) {
  160. startWrite();
  161. SPI_WRITE16(color);
  162. endWrite();
  163. }
  164. void Adafruit_SPITFT::writePixel(uint16_t color){
  165. SPI_WRITE16(color);
  166. }
  167. void Adafruit_SPITFT::writePixels(uint16_t * colors, uint32_t len){
  168. SPI_WRITE_PIXELS((uint8_t*)colors , len * 2);
  169. }
  170. void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len){
  171. #ifdef SPI_HAS_WRITE_PIXELS
  172. if(_sclk >= 0){
  173. for (uint32_t t=0; t<len; t++){
  174. writePixel(color);
  175. }
  176. return;
  177. }
  178. static uint16_t temp[SPI_MAX_PIXELS_AT_ONCE];
  179. size_t blen = (len > SPI_MAX_PIXELS_AT_ONCE)?SPI_MAX_PIXELS_AT_ONCE:len;
  180. uint16_t tlen = 0;
  181. for (uint32_t t=0; t<blen; t++){
  182. temp[t] = color;
  183. }
  184. while(len){
  185. tlen = (len>blen)?blen:len;
  186. writePixels(temp, tlen);
  187. len -= tlen;
  188. }
  189. #else
  190. uint8_t hi = color >> 8, lo = color;
  191. if(_sclk < 0){ //AVR Optimization
  192. for (uint32_t t=len; t; t--){
  193. HSPI_WRITE(hi);
  194. HSPI_WRITE(lo);
  195. }
  196. return;
  197. }
  198. for (uint32_t t=len; t; t--){
  199. spiWrite(hi);
  200. spiWrite(lo);
  201. }
  202. #endif
  203. }
  204. void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) {
  205. if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
  206. setAddrWindow(x,y,1,1);
  207. writePixel(color);
  208. }
  209. void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){
  210. if((x >= _width) || (y >= _height)) return;
  211. int16_t x2 = x + w - 1, y2 = y + h - 1;
  212. if((x2 < 0) || (y2 < 0)) return;
  213. // Clip left/top
  214. if(x < 0) {
  215. x = 0;
  216. w = x2 + 1;
  217. }
  218. if(y < 0) {
  219. y = 0;
  220. h = y2 + 1;
  221. }
  222. // Clip right/bottom
  223. if(x2 >= _width) w = _width - x;
  224. if(y2 >= _height) h = _height - y;
  225. int32_t len = (int32_t)w * h;
  226. setAddrWindow(x, y, w, h);
  227. writeColor(color, len);
  228. }
  229. void Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){
  230. writeFillRect(x, y, 1, h, color);
  231. }
  232. void Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){
  233. writeFillRect(x, y, w, 1, color);
  234. }
  235. void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color){
  236. startWrite();
  237. writePixel(x, y, color);
  238. endWrite();
  239. }
  240. void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y,
  241. int16_t h, uint16_t color) {
  242. startWrite();
  243. writeFastVLine(x, y, h, color);
  244. endWrite();
  245. }
  246. void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y,
  247. int16_t w, uint16_t color) {
  248. startWrite();
  249. writeFastHLine(x, y, w, color);
  250. endWrite();
  251. }
  252. void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
  253. uint16_t color) {
  254. startWrite();
  255. writeFillRect(x,y,w,h,color);
  256. endWrite();
  257. }
  258. // Adapted from https://github.com/PaulStoffregen/ILI9341_t3
  259. // by Marc MERLIN. See examples/pictureEmbed to use this.
  260. // 5/6/2017: function name and arguments have changed for compatibility
  261. // with current GFX library and to avoid naming problems in prior
  262. // implementation. Formerly drawBitmap() with arguments in different order.
  263. void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y,
  264. uint16_t *pcolors, int16_t w, int16_t h) {
  265. int16_t x2, y2; // Lower-right coord
  266. if(( x >= _width ) || // Off-edge right
  267. ( y >= _height) || // " top
  268. ((x2 = (x+w-1)) < 0 ) || // " left
  269. ((y2 = (y+h-1)) < 0) ) return; // " bottom
  270. int16_t bx1=0, by1=0, // Clipped top-left within bitmap
  271. saveW=w; // Save original bitmap width value
  272. if(x < 0) { // Clip left
  273. w += x;
  274. bx1 = -x;
  275. x = 0;
  276. }
  277. if(y < 0) { // Clip top
  278. h += y;
  279. by1 = -y;
  280. y = 0;
  281. }
  282. if(x2 >= _width ) w = _width - x; // Clip right
  283. if(y2 >= _height) h = _height - y; // Clip bottom
  284. pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left
  285. startWrite();
  286. setAddrWindow(x, y, w, h); // Clipped area
  287. while(h--) { // For each (clipped) scanline...
  288. writePixels(pcolors, w); // Push one (clipped) row
  289. pcolors += saveW; // Advance pointer by one full (unclipped) line
  290. }
  291. endWrite();
  292. }
  293. #endif // !__AVR_ATtiny85__