mirror of
				https://github.com/esp8266/Arduino.git
				synced 2025-11-03 14:33:37 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			349 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			349 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
  TFT Touch Shield 2.0 examples - tftbmp2
 | 
						|
  
 | 
						|
  loovee
 | 
						|
  2013-1-21
 | 
						|
  
 | 
						|
  this demo can show all bmp file in root Directory of SD card
 | 
						|
  please ensure that your image file is 320x240 size. 
 | 
						|
 | 
						|
  MAX_BMP can config the max file to display
 | 
						|
  FILENAME_LEN can config the max length of file name
 | 
						|
  
 | 
						|
*/
 | 
						|
 | 
						|
#include <SD.h>
 | 
						|
#include <SPI.h>
 | 
						|
#include <Streaming.h>
 | 
						|
 | 
						|
#include "TFTv2.h"
 | 
						|
 | 
						|
#define MAX_BMP         10                      // bmp file num
 | 
						|
#define FILENAME_LEN    20                      // max file name length
 | 
						|
 | 
						|
const int PIN_SD_CS = 4;                        // pin of sd card
 | 
						|
 | 
						|
const long __Gnbmp_height = 320;                 // bmp hight
 | 
						|
const long __Gnbmp_width  = 240;                 // bmp width
 | 
						|
 | 
						|
long __Gnbmp_image_offset  = 0;;
 | 
						|
 | 
						|
int __Gnfile_num = 0;                           // num of file
 | 
						|
char __Gsbmp_files[MAX_BMP][FILENAME_LEN];      // file name
 | 
						|
 | 
						|
File bmpFile;
 | 
						|
 | 
						|
// if bmp file return 1, else return 0
 | 
						|
bool checkBMP(char *_name, char r_name[])
 | 
						|
{
 | 
						|
    int len = 0;
 | 
						|
 | 
						|
    if(NULL == _name)return false;
 | 
						|
    
 | 
						|
    while(*_name)
 | 
						|
    {
 | 
						|
        r_name[len++] = *(_name++);
 | 
						|
        if(len>FILENAME_LEN)return false;
 | 
						|
    }
 | 
						|
 | 
						|
    r_name[len] = '\0';
 | 
						|
 | 
						|
    if(len < 5)return false;
 | 
						|
 | 
						|
    // if xxx.bmp or xxx.BMP
 | 
						|
    if( r_name[len-4] == '.' \
 | 
						|
        && (r_name[len-3] == 'b' || (r_name[len-3] == 'B')) \
 | 
						|
        && (r_name[len-2] == 'm' || (r_name[len-2] == 'M')) \
 | 
						|
        && (r_name[len-1] == 'p' || (r_name[len-1] == 'P')) )
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// search root to find bmp file
 | 
						|
void searchDirectory()
 | 
						|
{
 | 
						|
    File root = SD.open("/");                       // root
 | 
						|
    while(true) 
 | 
						|
    {
 | 
						|
        File entry =  root.openNextFile();
 | 
						|
        
 | 
						|
        if (! entry)
 | 
						|
        {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if(!entry.isDirectory())
 | 
						|
        {
 | 
						|
            char *ptmp = entry.name();
 | 
						|
 | 
						|
            char __Name[20];
 | 
						|
 | 
						|
            if(checkBMP(ptmp, __Name))
 | 
						|
            {
 | 
						|
                Serial.println(__Name);
 | 
						|
 | 
						|
                strcpy(__Gsbmp_files[__Gnfile_num++], __Name);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        entry.close();
 | 
						|
    }
 | 
						|
    
 | 
						|
    Serial.print("get ");
 | 
						|
    Serial.print(__Gnfile_num);
 | 
						|
    Serial.println(" file: ");
 | 
						|
    
 | 
						|
    for(int i=0; i<__Gnfile_num; i++)
 | 
						|
    {
 | 
						|
        Serial.println(__Gsbmp_files[i]);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void setup()
 | 
						|
{
 | 
						|
 | 
						|
    Serial.begin(115200);
 | 
						|
    
 | 
						|
    pinMode(PIN_SD_CS,OUTPUT);
 | 
						|
    digitalWrite(PIN_SD_CS,HIGH);
 | 
						|
 | 
						|
    Tft.TFTinit();
 | 
						|
 | 
						|
    Sd2Card card;
 | 
						|
    card.init(SPI_FULL_SPEED, PIN_SD_CS); 
 | 
						|
    
 | 
						|
    if(!SD.begin(PIN_SD_CS))              
 | 
						|
    { 
 | 
						|
        Serial.println("failed!");
 | 
						|
        while(1);                               // init fail, die here
 | 
						|
    }
 | 
						|
    
 | 
						|
    Serial.println("SD OK!");
 | 
						|
    
 | 
						|
    searchDirectory();
 | 
						|
 | 
						|
    TFT_BL_ON;
 | 
						|
}
 | 
						|
 | 
						|
void loop()
 | 
						|
{
 | 
						|
/*
 | 
						|
    static int dirCtrl = 0;
 | 
						|
    for(unsigned char i=0; i<__Gnfile_num; i++)
 | 
						|
    {
 | 
						|
        bmpFile = SD.open(__Gsbmp_files[i]);
 | 
						|
        if (! bmpFile)
 | 
						|
        {
 | 
						|
            Serial.println("didnt find image");
 | 
						|
            while (1);
 | 
						|
        }
 | 
						|
 | 
						|
        if(! bmpReadHeader(bmpFile)) 
 | 
						|
        {
 | 
						|
            Serial.println("bad bmp");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        dirCtrl = 1-dirCtrl;
 | 
						|
        bmpdraw(bmpFile, 0, 0, dirCtrl);
 | 
						|
        bmpFile.close();
 | 
						|
 | 
						|
        delay(1000);
 | 
						|
    }
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
        bmpFile = SD.open("pfvm_1.bmp");
 | 
						|
        
 | 
						|
        if (! bmpFile)
 | 
						|
        {
 | 
						|
            Serial.println("didnt find image");
 | 
						|
            while (1);
 | 
						|
        }
 | 
						|
 | 
						|
        if(! bmpReadHeader(bmpFile)) 
 | 
						|
        {
 | 
						|
            Serial.println("bad bmp");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        bmpdraw(bmpFile, 0, 0, 1);
 | 
						|
        bmpFile.close();
 | 
						|
 | 
						|
        while(1);
 | 
						|
}
 | 
						|
 | 
						|
/*********************************************/
 | 
						|
// This procedure reads a bitmap and draws it to the screen
 | 
						|
// its sped up by reading many pixels worth of data at a time
 | 
						|
// instead of just one pixel at a time. increading the buffer takes
 | 
						|
// more RAM but makes the drawing a little faster. 20 pixels' worth
 | 
						|
// is probably a good place
 | 
						|
 | 
						|
#define BUFFPIXEL       60                          // must be a divisor of 240 
 | 
						|
#define BUFFPIXEL_X3    180                         // BUFFPIXELx3
 | 
						|
 | 
						|
 | 
						|
#define UP_DOWN     1
 | 
						|
#define DOWN_UP     0
 | 
						|
 | 
						|
// dir - 1: up to down
 | 
						|
// dir - 2: down to up
 | 
						|
void bmpdraw(File f, int x, int y, int dir)
 | 
						|
{
 | 
						|
 | 
						|
    if(bmpFile.seek(__Gnbmp_image_offset))
 | 
						|
    {
 | 
						|
        Serial.print("pos = ");
 | 
						|
        Serial.println(bmpFile.position());
 | 
						|
    }
 | 
						|
    
 | 
						|
    uint32_t time = millis();
 | 
						|
 | 
						|
    uint8_t sdbuffer[BUFFPIXEL_X3];                                         // 3 * pixels to buffer
 | 
						|
 | 
						|
    for (int i=0; i< __Gnbmp_height; i++)
 | 
						|
    {
 | 
						|
        if(dir)
 | 
						|
        {
 | 
						|
            bmpFile.seek(__Gnbmp_image_offset+(__Gnbmp_height-1-i)*240*3);
 | 
						|
        }
 | 
						|
 | 
						|
        for(int j=0; j<(240/BUFFPIXEL); j++)
 | 
						|
        {
 | 
						|
        
 | 
						|
            bmpFile.read(sdbuffer, BUFFPIXEL_X3);
 | 
						|
            uint8_t buffidx = 0;
 | 
						|
            int offset_x = j*BUFFPIXEL;
 | 
						|
            
 | 
						|
            unsigned int __color[BUFFPIXEL];
 | 
						|
            
 | 
						|
            for(int k=0; k<BUFFPIXEL; k++)
 | 
						|
            {
 | 
						|
                __color[k] = sdbuffer[buffidx+2]>>3;                        // read
 | 
						|
                __color[k] = __color[k]<<6 | (sdbuffer[buffidx+1]>>2);      // green
 | 
						|
                __color[k] = __color[k]<<5 | (sdbuffer[buffidx+0]>>3);      // blue
 | 
						|
                
 | 
						|
                buffidx += 3;
 | 
						|
            }
 | 
						|
 | 
						|
            Tft.setCol(offset_x, offset_x+BUFFPIXEL);
 | 
						|
 | 
						|
            if(dir)
 | 
						|
            {
 | 
						|
                Tft.setPage(i, i);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Tft.setPage(__Gnbmp_height-i-1, __Gnbmp_height-i-1);
 | 
						|
            }
 | 
						|
 | 
						|
            Tft.sendCMD(0x2c);                                                  
 | 
						|
            
 | 
						|
            TFT_DC_HIGH;
 | 
						|
            TFT_CS_LOW;
 | 
						|
 | 
						|
            for(int m=0; m < BUFFPIXEL; m++)
 | 
						|
            {
 | 
						|
                SPI.transfer(__color[m]>>8);
 | 
						|
                SPI.transfer(__color[m]);
 | 
						|
                
 | 
						|
                delay(10);
 | 
						|
            }
 | 
						|
 | 
						|
            TFT_CS_HIGH;
 | 
						|
        }
 | 
						|
        
 | 
						|
    }
 | 
						|
    
 | 
						|
    Serial.print(millis() - time, DEC);
 | 
						|
    Serial.println(" ms");
 | 
						|
}
 | 
						|
 | 
						|
boolean bmpReadHeader(File f) 
 | 
						|
{
 | 
						|
    // read header
 | 
						|
    uint32_t tmp;
 | 
						|
    uint8_t bmpDepth;
 | 
						|
    
 | 
						|
    if (read16(f) != 0x4D42) {
 | 
						|
        // magic bytes missing
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    // read file size
 | 
						|
    tmp = read32(f);
 | 
						|
    Serial.print("size 0x");
 | 
						|
    Serial.println(tmp, HEX);
 | 
						|
 | 
						|
    // read and ignore creator bytes
 | 
						|
    read32(f);
 | 
						|
 | 
						|
    __Gnbmp_image_offset = read32(f);
 | 
						|
    Serial.print("offset ");
 | 
						|
    Serial.println(__Gnbmp_image_offset, DEC);
 | 
						|
 | 
						|
    // read DIB header
 | 
						|
    tmp = read32(f);
 | 
						|
    Serial.print("header size ");
 | 
						|
    Serial.println(tmp, DEC);
 | 
						|
    
 | 
						|
    int bmp_width = read32(f);
 | 
						|
    int bmp_height = read32(f);
 | 
						|
    
 | 
						|
    if(bmp_width != __Gnbmp_width || bmp_height != __Gnbmp_height)      // if image is not 320x240, return false
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (read16(f) != 1)
 | 
						|
    return false;
 | 
						|
 | 
						|
    bmpDepth = read16(f);
 | 
						|
    Serial.print("bitdepth ");
 | 
						|
    Serial.println(bmpDepth, DEC);
 | 
						|
 | 
						|
    if (read32(f) != 0) {
 | 
						|
        // compression not supported!
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    Serial.print("compression ");
 | 
						|
    Serial.println(tmp, DEC);
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
/*********************************************/
 | 
						|
// These read data from the SD card file and convert them to big endian
 | 
						|
// (the data is stored in little endian format!)
 | 
						|
 | 
						|
// LITTLE ENDIAN!
 | 
						|
uint16_t read16(File f)
 | 
						|
{
 | 
						|
    uint16_t d;
 | 
						|
    uint8_t b;
 | 
						|
    b = f.read();
 | 
						|
    d = f.read();
 | 
						|
    d <<= 8;
 | 
						|
    d |= b;
 | 
						|
    return d;
 | 
						|
}
 | 
						|
 | 
						|
// LITTLE ENDIAN!
 | 
						|
uint32_t read32(File f)
 | 
						|
{
 | 
						|
    uint32_t d;
 | 
						|
    uint16_t b;
 | 
						|
 | 
						|
    b = read16(f);
 | 
						|
    d = read16(f);
 | 
						|
    d <<= 16;
 | 
						|
    d |= b;
 | 
						|
    return d;
 | 
						|
}
 |