1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00
Andrey Filimonov 4626a9df80 Initial ESP8266 HW SPI implementation
ILI9341 lib as a client for SPI lib
2015-04-01 07:10:31 +03:00

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;
}