From 9d635142aff7ca2af4fb648e1d0cb2e27ca5b71f Mon Sep 17 00:00:00 2001 From: slaff Date: Fri, 18 Nov 2016 13:39:10 +0100 Subject: [PATCH] Feature/bmp for screentft (#805) * added BMP image displayed on screen in sample project * Small fixes to the proposed changes. --- .../Adafruit_ILI9341/Adafruit_ILI9341.cpp | 4 +- .../Adafruit_ILI9341/Adafruit_ILI9341.h | 1 + .../Makefile-user.mk | 4 +- .../ScreenTFT_ILI9340-ILI9341/app/BMPDraw.cpp | 168 ++++++++++++++++++ .../ScreenTFT_ILI9340-ILI9341/app/BPMDraw.h | 24 +++ .../app/application.cpp | 15 +- .../ScreenTFT_ILI9340-ILI9341/files/sming.bmp | Bin 0 -> 49208 bytes 7 files changed, 211 insertions(+), 5 deletions(-) create mode 100644 samples/ScreenTFT_ILI9340-ILI9341/app/BMPDraw.cpp create mode 100644 samples/ScreenTFT_ILI9340-ILI9341/app/BPMDraw.h create mode 100644 samples/ScreenTFT_ILI9340-ILI9341/files/sming.bmp diff --git a/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp b/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp index d1c2ca81c5..05a69695da 100644 --- a/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp +++ b/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp @@ -18,7 +18,6 @@ ********************************/ #include "Adafruit_ILI9341.h" -#include #include "pins_arduino.h" #include "wiring_private.h" #include @@ -171,6 +170,9 @@ void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color) { transmitData(SWAPBYTES(color)); } +void Adafruit_ILI9341::pushColor(uint16_t color) { + transmitData(SWAPBYTES(color)); +} void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h, diff --git a/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.h b/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.h index 6276b5a5fc..cb7822a0c0 100644 --- a/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.h +++ b/Sming/Libraries/Adafruit_ILI9341/Adafruit_ILI9341.h @@ -142,6 +142,7 @@ class Adafruit_ILI9341 : public Adafruit_GFX { void begin(void), fillScreen(uint16_t color), + pushColor(uint16_t color), drawPixel(int16_t x, int16_t y, uint16_t color), drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), diff --git a/samples/ScreenTFT_ILI9340-ILI9341/Makefile-user.mk b/samples/ScreenTFT_ILI9340-ILI9341/Makefile-user.mk index bd088ca354..48064da273 100644 --- a/samples/ScreenTFT_ILI9340-ILI9341/Makefile-user.mk +++ b/samples/ScreenTFT_ILI9340-ILI9341/Makefile-user.mk @@ -34,6 +34,6 @@ # SPI_MODE = dio ## SPIFFS options -DISABLE_SPIFFS = 1 -# SPIFF_FILES = files +#DISABLE_SPIFFS = 1 +SPIFF_FILES = files diff --git a/samples/ScreenTFT_ILI9340-ILI9341/app/BMPDraw.cpp b/samples/ScreenTFT_ILI9340-ILI9341/app/BMPDraw.cpp new file mode 100644 index 0000000000..319d531bcf --- /dev/null +++ b/samples/ScreenTFT_ILI9340-ILI9341/app/BMPDraw.cpp @@ -0,0 +1,168 @@ +/*************************************************** + This is a library for the Adafruit 1.8" SPI display. + +This library works with the Adafruit 1.8" TFT Breakout w/SD card + ----> http://www.adafruit.com/products/358 +The 1.8" TFT shield + ----> https://www.adafruit.com/product/802 +The 1.44" TFT breakout + ----> https://www.adafruit.com/product/2088 +as well as Adafruit raw 1.8" TFT display + ----> http://www.adafruit.com/products/618 + + Check out the links above for our tutorials and wiring diagrams + These displays use SPI to communicate, 4 or 5 pins are required to + interface (RST is optional) + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + MIT license, all text above must be included in any redistribution + ****************************************************/ +/**************************************************** + * ported for Sming by H.Boettcher. + * this implementation uses spifs storage instead of SD cards + * hbottc@gmail.com + ***************************************************/ + + +#include +#include +#include + +#include "BPMDraw.h" + + +// This function opens a Windows Bitmap (BMP) file and +// displays it at the given coordinates. It's sped up +// by reading many pixels worth of data at a time +// (rather than pixel by pixel). Increasing the buffer +// size takes more of the esp8266's precious RAM but +// makes loading a little faster. 20 pixels seems a +// good balance. + +void bmpDraw(Adafruit_ILI9341 tft, String fileName, uint8_t x, uint8_t y) { + + file_t handle; + + int bmpWidth, bmpHeight; // W+H in pixels + uint8_t bmpDepth; // Bit depth (currently must be 24) + uint32_t bmpImageoffset; // Start of image data in file + uint32_t rowSize; // Not always = bmpWidth; may have padding + uint8_t sdbuffer[3 * BUFFPIXEL]; // pixel buffer (R+G+B per pixel) + uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer + boolean goodBmp = false; // Set to true on valid header parse + boolean flip = true; // BMP is stored bottom-to-top + int w, h, row, col; + uint8_t r, g, b; + uint32_t pos = 0, startTime = millis(); + + if ((x >= tft.width()) || (y >= tft.height())) + return; + + Serial.println(); + Serial.print("Loading image '"); + Serial.print(fileName); + Serial.println('\''); + + handle = fileOpen(fileName.c_str(), eFO_ReadOnly); + if (handle == -1) + { + debugf("File wasn't found: %s", fileName.c_str()); + fileClose(handle); + return; + } + + // Parse BMP header + if (read16(handle) == 0x4D42) { // BMP signature + debugf("File size: %d\n", read32(handle)); // get File Size + (void)read32(handle); // Read & ignore creator bytes + bmpImageoffset = read32(handle); // Start of image data + debugf("Image Offset: %d\n", bmpImageoffset); + debugf("Header size: %d\n", read32(handle)); // Read DIB header + bmpWidth = read32(handle); + bmpHeight = read32(handle); + if(read16(handle) == 1) { // # planes -- must be '1' + bmpDepth = read16(handle); // bits per pixel + debugf("Bit Depth: %d\n", bmpDepth); + if((bmpDepth == 24) && (read32(handle) == 0)) { // 0 = uncompressed + goodBmp = true; // Supported BMP format -- proceed! + + debugf("Image size: %d x %d\n", bmpWidth, bmpHeight); + + // BMP rows are padded (if needed) to 4-byte boundary + rowSize = (bmpWidth * 3 + 3) & ~3; + + // If bmpHeight is negative, image is in top-down order. + // This is not canon but has been observed in the wild. + if(bmpHeight < 0) { + bmpHeight = -bmpHeight; + flip = false; + } + + // Crop area to be loaded + w = bmpWidth; + h = bmpHeight; + if((x+w-1) >= tft.width()) w = tft.width() - x; + if((y+h-1) >= tft.height()) h = tft.height() - y; + + // Set TFT address window to clipped image bounds + tft.setAddrWindow(x, y, x+w-1, y+h-1); + + for (row=0; row= sizeof(sdbuffer)) { // Indeed + fileRead(handle, sdbuffer, sizeof(sdbuffer)); + buffidx = 0; // Set index to beginning + } + + // Convert pixel from BMP to TFT format, push to display + b = sdbuffer[buffidx++]; + g = sdbuffer[buffidx++]; + r = sdbuffer[buffidx++]; + tft.pushColor(tft.color565(r,g,b)); + } // end pixel + } // end scanline + Serial.printf("Loaded in %d ms\n", millis() - startTime); + } // end goodBmp + } + } + + fileClose(handle); + if(!goodBmp) Serial.println("BMP format not recognized."); +} + +// These read 16- and 32-bit types from the spifs file. +// BMP data is stored little-endian, esp8266 is little-endian too. +// May need to reverse subscript order if porting elsewhere. + +uint16_t read16(file_t f) { + char bytes[2]; + fileRead(f, bytes, 2); + return (bytes[1] << 8) + bytes[0]; +} + +uint32_t read32(file_t f) { + char bytes[4]; + fileRead(f, bytes, 4); + return (bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0]; +} + + diff --git a/samples/ScreenTFT_ILI9340-ILI9341/app/BPMDraw.h b/samples/ScreenTFT_ILI9340-ILI9341/app/BPMDraw.h new file mode 100644 index 0000000000..02dc688b75 --- /dev/null +++ b/samples/ScreenTFT_ILI9340-ILI9341/app/BPMDraw.h @@ -0,0 +1,24 @@ +#ifndef _BMPDRAWH_ +#define _BMPDRAWH_ + +// This function opens a Windows Bitmap (BMP) file and +// displays it at the given coordinates. It's sped up +// by reading many pixels worth of data at a time +// (rather than pixel by pixel). Increasing the buffer +// size takes more of the esp8266's precious RAM but +// makes loading a little faster. 20 pixels seems a +// good balance. + +#define BUFFPIXEL 20 + +void bmpDraw(Adafruit_ILI9341 tft, String filename, uint8_t x, uint8_t y); + +// These read 16- and 32-bit types from the spifs file. +// BMP data is stored little-endian, esp8266 is little-endian too. +// May need to reverse subscript order if porting elsewhere. + +uint16_t read16(file_t f); + +uint32_t read32(file_t f); + +#endif diff --git a/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp b/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp index 36bac0f5df..98520cb3a1 100644 --- a/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp +++ b/samples/ScreenTFT_ILI9340-ILI9341/app/application.cpp @@ -2,6 +2,9 @@ #include #include +#include "BPMDraw.h" + + // If you want, you can define WiFi settings globally in Eclipse Environment Variables #ifndef WIFI_SSID #define WIFI_SSID "PleaseEnterSSID" // Put you SSID and Password here @@ -38,6 +41,14 @@ int satir=6; String lists[]={"a","b","c","d","e","f"}; + +void basicBPM() { + tft.fillScreen(ILI9341_BLACK); // Clear display + tft.setRotation(tft.getRotation() + 1); // Inc rotation 90 degrees + for (uint8_t i = 0; i < 4; i++) // Draw 4 parrots + bmpDraw(tft, "sming.bmp", tft.width() / 4 * i, tft.height() / 4 * i); +} + void basicGui() { tft.setTextSize(1); @@ -64,7 +75,7 @@ void basicGui() } p1=50; r++; - + guiTimer.initializeMs(1000, basicBPM).start(false); } void init() @@ -97,7 +108,7 @@ void init() tft.println("M.Bozkurt"); delay(2000); tft.fillScreen(0); - guiTimer.initializeMs(1000, basicGui).start(); + guiTimer.initializeMs(1000, basicGui).start(false); //runTest(); } diff --git a/samples/ScreenTFT_ILI9340-ILI9341/files/sming.bmp b/samples/ScreenTFT_ILI9340-ILI9341/files/sming.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b566de5c5e778a573567464312560b16ac4d8725 GIT binary patch literal 49208 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 A%>V!Z literal 0 HcmV?d00001