PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
5.2KB

  1. /*
  2. An SD bmp image load example. (extracted and modded by Adafruit old library http://www.adafruit.com )
  3. This use NOT the adafruit SD library (or the standard arduino SD!)
  4. but SdFat created by bill greiman https://github.com/greiman/SdFat much better to me!!!
  5. Note about SPI Transactions <-------------------------------------------
  6. To enable compatibility for SPI Transactions please open
  7. SfFatCinfig.h in SdFat libary and set
  8. #define ENABLE_SPI_TRANSACTION 0
  9. to
  10. #define ENABLE_SPI_TRANSACTION 1
  11. */
  12. #include <SPI.h>
  13. #include <SdFat.h>
  14. #include <Adafruit_GFX.h>
  15. #include <TFT_ILI9163C.h>
  16. //PINS
  17. #define __CS 10
  18. #define __DC 9
  19. #define __SDCS 2
  20. // This function opens a Windows Bitmap (BMP) file and
  21. // displays it at the given coordinates. It's sped up
  22. // by reading many pixels worth of data at a time
  23. // (rather than pixel by pixel). Increasing the buffer
  24. // size takes more of the Arduino's precious RAM but
  25. // makes loading a little faster. 20 pixels seems a
  26. // good balance.
  27. #define BUFFPIXEL 20
  28. boolean SDInited = true;
  29. TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC);
  30. SdFat SD;
  31. SdFile myFile;
  32. void setup(void) {
  33. Serial.begin(9600);
  34. tft.begin();
  35. //tft.setRotation(2);
  36. //I have a crappy chinese SD card holder that it's not compatible
  37. //with hi speeds SPI (SPI_FULL_SPEED). If you have better luck set it to
  38. //SPI_FULL_SPEED
  39. if (!SD.begin(__SDCS,SPI_HALF_SPEED)) {
  40. tft.setCursor(0,0);
  41. tft.print("sd failed!");
  42. SDInited = false;
  43. }
  44. Serial.println("OK!");
  45. //your image here!
  46. bmpDraw("star.bmp", 0, 0);
  47. }
  48. void loop() {
  49. }
  50. void bmpDraw(const char *filename, uint8_t x, uint16_t y) {
  51. if (SDInited){
  52. File bmpFile;
  53. uint16_t bmpWidth, bmpHeight; // W+H in pixels
  54. uint8_t bmpDepth; // Bit depth (currently must be 24)
  55. uint32_t bmpImageoffset; // Start of image data in file
  56. uint32_t rowSize; // Not always = bmpWidth; may have padding
  57. uint8_t sdbufferLen = BUFFPIXEL * 3;
  58. uint8_t sdbuffer[sdbufferLen]; // pixel buffer (R+G+B per pixel)
  59. uint8_t buffidx = sdbufferLen; // Current position in sdbuffer
  60. boolean goodBmp = false; // Set to true on valid header parse
  61. boolean flip = true; // BMP is stored bottom-to-top
  62. uint16_t w, h, row, col;
  63. uint8_t r, g, b;
  64. uint32_t pos = 0;
  65. if((x >= tft.width()) || (y >= tft.height())) return;
  66. // Open requested file on SD card
  67. if ((bmpFile = SD.open(filename)) == false) {
  68. tft.setCursor(0,0);
  69. tft.print("file not found!");
  70. return;
  71. }
  72. // Parse BMP header
  73. if(read16(bmpFile) == 0x4D42) { // BMP signature
  74. read32(bmpFile);
  75. (void)read32(bmpFile); // Read & ignore creator bytes
  76. bmpImageoffset = read32(bmpFile); // Start of image data
  77. // Read DIB header
  78. read32(bmpFile);
  79. bmpWidth = read32(bmpFile);
  80. bmpHeight = read32(bmpFile);
  81. if(read16(bmpFile) == 1) { // # planes -- must be '1'
  82. bmpDepth = read16(bmpFile); // bits per pixel
  83. if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
  84. goodBmp = true; // Supported BMP format -- proceed!
  85. rowSize = (bmpWidth * 3 + 3) & ~3;// BMP rows are padded (if needed) to 4-byte boundary
  86. if (bmpHeight < 0) {
  87. bmpHeight = -bmpHeight;
  88. flip = false;
  89. }
  90. // Crop area to be loaded
  91. w = bmpWidth;
  92. h = bmpHeight;
  93. if((x+w-1) >= tft.width()) w = tft.width() - x;
  94. if((y+h-1) >= tft.height()) h = tft.height() - y;
  95. tft.startPushData(x, y, x+w-1, y+h-1);
  96. for (row=0; row<h; row++) { // For each scanline...
  97. if (flip){ // Bitmap is stored bottom-to-top order (normal BMP)
  98. pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
  99. }
  100. else { // Bitmap is stored top-to-bottom
  101. pos = bmpImageoffset + row * rowSize;
  102. }
  103. if (bmpFile.position() != pos) { // Need seek?
  104. bmpFile.seek(pos);
  105. buffidx = sdbufferLen; // Force buffer reload
  106. }
  107. for (col=0; col<w; col++) { // For each pixel...
  108. // Time to read more pixel data?
  109. if (buffidx >= sdbufferLen) { // Indeed
  110. bmpFile.read(sdbuffer, sdbufferLen);
  111. buffidx = 0; // Set index to beginning
  112. }
  113. // Convert pixel from BMP to TFT format, push to display
  114. b = sdbuffer[buffidx++];
  115. g = sdbuffer[buffidx++];
  116. r = sdbuffer[buffidx++];
  117. tft.pushData(tft.Color565(r,g,b));
  118. } // end pixel
  119. } // end scanline
  120. tft.endPushData();
  121. } // end goodBmp
  122. }
  123. }
  124. bmpFile.close();
  125. if(!goodBmp) {
  126. tft.setCursor(0,0);
  127. tft.print("file unrecognized!");
  128. }
  129. }
  130. }
  131. uint16_t read16(File &f) {
  132. uint16_t result;
  133. ((uint8_t *)&result)[0] = f.read(); // LSB
  134. ((uint8_t *)&result)[1] = f.read(); // MSB
  135. return result;
  136. }
  137. uint32_t read32(File &f) {
  138. uint32_t result;
  139. ((uint8_t *)&result)[0] = f.read(); // LSB
  140. ((uint8_t *)&result)[1] = f.read();
  141. ((uint8_t *)&result)[2] = f.read();
  142. ((uint8_t *)&result)[3] = f.read(); // MSB
  143. return result;
  144. }