Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
src/FT_Hal_Utils.cpp
- Committer:
- JackB
- Date:
- 2018-07-23
- Revision:
- 10:6a81aeca25e3
- Parent:
- 5:506e2de9a9e6
File content as of revision 10:6a81aeca25e3:
#include "FT_Platform.h"
#include "mbed.h"
//#include "SDFileSystem.h"
#define DEBUG
/* meta-commands, sequences of several display-list entries condensed into simpler to use functions at the price of some overhead */
ft_void_t FT813::Point(ft_int16_t x, ft_int16_t y, ft_uint16_t size)
{
ft_uint32_t calc;
StartFunc(FT_CMD_SIZE*4);
SendCmd(DL_BEGIN | FT8_POINTS);
calc = POINT_SIZE(size*16);
SendCmd(calc);
calc = VERTEX2F(x * 16, y * 16);
SendCmd(calc);
SendCmd(DL_END);
EndFunc();
}
ft_void_t FT813::Line(ft_int16_t x0, ft_int16_t y0, ft_int16_t x1, ft_int16_t y1, ft_int16_t width)
{
ft_uint32_t calc;
StartFunc(FT_CMD_SIZE*5);
SendCmd(DL_BEGIN | FT8_LINES);
calc = LINE_WIDTH(width * 16);
SendCmd(calc);
calc = VERTEX2F(x0 * 16, y0 * 16);
SendCmd(calc);
calc = VERTEX2F(x1 * 16, y1 * 16);
SendCmd(calc);
SendCmd(DL_END);
EndFunc();
}
ft_void_t FT813::Rect(ft_int16_t x0, ft_int16_t y0, ft_int16_t x1, ft_int16_t y1, ft_int16_t corner)
{
ft_uint32_t calc;
StartFunc(FT_CMD_SIZE*5);
SendCmd(DL_BEGIN | FT8_RECTS);
calc = LINE_WIDTH(corner * 16);
SendCmd(calc);
calc = VERTEX2F(x0 * 16, y0 * 16);
SendCmd(calc);
calc = VERTEX2F(x1 * 16, y1 * 16);
SendCmd(calc);
SendCmd(DL_END);
EndFunc();
}
ft_void_t FT813::RectWH(ft_int16_t x0, ft_int16_t y0, ft_int16_t w, ft_int16_t h, ft_int16_t corner)
{
ft_uint32_t calc;
x0 += corner;
y0 += corner;
w -= corner*2;
h -= corner*2;
ft_int16_t x1 = x0 + w;
ft_int16_t y1 = y0 + h;
StartFunc(FT_CMD_SIZE*5);
SendCmd(DL_BEGIN | FT8_RECTS);
calc = LINE_WIDTH(corner * 16);
SendCmd(calc);
calc = VERTEX2F(x0 * 16, y0 * 16);
SendCmd(calc);
calc = VERTEX2F(x1 * 16, y1 * 16);
SendCmd(calc);
SendCmd(DL_END);
EndFunc();
}
/* Function to load JPG file from the filesystem into the FT800 buffer. */
/* First the graphics data have to be load into the FT800 buffer. */
/* The FT800 will decode the JPG data into a bitmap. */
/* In the second step this bitmap will displayed on the LCD. */
/* return 0 if jpg is ok */
/* return x_size and y_size of jpg */
ft_uint8_t FT813::LoadJpg(char* filename, ft_int16_t* x_size, ft_int16_t* y_size)
{
// unsigned char pbuff[8192];
int bufferSize = 8192;
// void* pbuff;
char* pbuff = (char*)malloc(bufferSize);
// char pbuff[BUFFER_SIZE] = {0};
unsigned short marker;
unsigned short length;
unsigned char data[4];
ft_uint16_t blocklen;
// printf("LoadJpg: Open filename \"%s\".\n", filename);
FILE *fp = fopen(filename, "rb");
if(fp == NULL) {
free(pbuff);
printf("LoadJpg: Cannot open file \"%s\".\n", filename);
return (-1); // cannot open file
}
// https://en.wikipedia.org/wiki/JPEG
// search for 0xFFC0 marker
fseek(fp, 0, SEEK_END);
unsigned int filesize = ftell(fp);
printf("LoadJpg: Size: %d.\n", filesize);
fseek(fp, 2, SEEK_SET); // Beginning of file
fread(data, 4, 1, fp); // Read first 4 bytes
marker = data[0] << 8 | data[1];
length = data[2] << 8 | data[3];
do {
if(marker == 0xFFC0)
break;
if(marker & 0xFF00 != 0xFF00)
break;
if (fseek(fp, length - 2,SEEK_CUR) != 0) // Skip marker
break;
fread(data, 4, 1, fp);
marker = data[0] << 8 | data[1];
length = data[2] << 8 | data[3];
} while(1);
if(marker != 0xFFC0) {
free(pbuff);
printf("LoadJpg: marker != 0xFFC0\n");
return (-2); // No FFC0 Marker, wrong format no baseline DCT-based JPEG
}
fseek(fp, 1, SEEK_CUR); // Skip marker
fread(data, 8, 1, fp); // Read next 8 bytes & extract height & width
*y_size = (data[0] << 8 | data[1]);
*x_size = (data[2] << 8 | data[3]);
uint16_t size_y = (data[0] << 8 | data[1]);
uint16_t size_x = (data[2] << 8 | data[3]);
uint16_t disp_x = DispWidth;
uint16_t disp_y = DispHeight;
if ((_orientation == FT8_DISPLAY_PORTRAIT_90CW) || (_orientation == FT8_DISPLAY_PORTRAIT_90CCW)) {
disp_x = DispHeight;
disp_y = DispWidth;
}
// http://www.ftdichip.com/Support/Documents/AppNotes/AN_339%20Using%20JPEGs%20with%20the%20FT800%20series.pdf, page 11
// if (marker_next_byte[0] == 0xC2){ //check if progressive JPEG
// error_code = 3;
// }
// if(*x_size > TFT.FT_DispWidth || *y_size > TFT.FT_DispHeight) return (-3); // to big to fit on screen
if(*x_size > disp_x || *y_size > disp_y)
{
free(pbuff);
printf("LoadJpg: Too big to fit on screen\n");
printf("LoadJpg: JPG (%dx%d) does not fit on TFT (%dx%d)\n", *x_size, *y_size, DispWidth, DispHeight);
return (-3); // Too big to fit on screen
}
// printf("LoadJpg: JPG (%dx%d) fits on TFT (%dx%d)\n", *x_size, *y_size, DispWidth, DispHeight);
fseek(fp, 0, SEEK_SET);
WrCmd32(CMD_LOADIMAGE);
WrCmd32(_address); //destination address of jpg decode
// Keep track of of the start addresses of loaded images
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
_address += (uint32_t) (size_x * size_y * 2);
_addresses[_bitmap_count] = _address;
// 0 OPT_RGB565
// 1 OPT_MONO
// 2 OPT_NODL
// 256 OPT_FLAT
// 256 OPT_SIGNED
// 512 OPT_CENTERX
// 1024 OPT_CENTERY
// 1536 OPT_CENTER
// 2048 OPT_RIGHTX
// 4096 OPT_NOBACK
// 8192 OPT_NOTICKS
WrCmd32(0); //output format of the bitmap - default is rgb565
while(filesize > 0) {
/* download the data into the command buffer by 8kb one shot */
blocklen = filesize > bufferSize ? bufferSize : filesize;
// printf("LoadJpg: blocklen: %d\n", blocklen);
// printf("LoadJpg: filesize: %d\n", filesize);
/* copy the data into pbuff and then transfter it to command buffer */
// int size = fread(&pbuff[0], 1, blocklen, fp);
int size = fread(pbuff, 1, blocklen, fp);
// printf("LoadJpg: fread: %d, %d\n", blocklen, size);
filesize -= blocklen;
/* copy data continuously into command memory */
// TFT.Ft_Gpu_Hal_WrCmdBuf(pbuff, blocklen); //alignment is already taken care by this api
WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
}
fclose(fp);
free(pbuff);
return(0);
}
ft_uint8_t FT813::LoadPng(char* filename, ft_int16_t* x_size, ft_int16_t* y_size)
{
int bufferSize = 8192;
ft_uint32_t filesize = 0;
ft_uint16_t blocklen = 0;
uint32_t marker1;
uint32_t marker2;
unsigned short length;
unsigned char data[32];
// printf("------------------------------\n");
printf("LoadPng: Filename \"%s\".\n", filename);
FILE *fp = fopen(filename, "rb");
if(fp == NULL) {
printf("LoadPng: Cannot open file \"%s\".\n", filename);
return (-1); // cannot open file
}
// Get file size
fseek(fp, 0, SEEK_END); // End of file
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET); // Beginning of file
printf("LoadPng: Filesize %d\n", filesize);
// search for 0x89504E47 and 0x0D0A1A0A markers "‰PNG...."
fread(data, 1, 32, fp); // Read first 32 bytes
// rewind(fp); // Beginning of file
fseek(fp, 0, SEEK_SET); // Beginning of file
// Check that this is indeed a PNG file
unsigned char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
// Make sure you have an IHDR
unsigned char ihdr_name[] = "IHDR";
if ((memcmp(data, png_header, 8)) || (memcmp(data+8+4, ihdr_name, 4))) {
printf("LoadPng: Invalid PNG file.\n");
return (-2); // No FFC0 Marker, wrong format no baseline DCT-based JPEG
}
// PNG actually stores integers in big-endian.
*x_size = ReadBigInt32(data, 24 - 8);
*y_size = ReadBigInt32(data, 24 - 4);
uint16_t size_x = ReadBigInt32(data, 24 - 8);
uint16_t size_y = ReadBigInt32(data, 24 - 4);
uint16_t disp_x = DispWidth;
uint16_t disp_y = DispHeight;
if ((_orientation == FT8_DISPLAY_PORTRAIT_90CW) || (_orientation == FT8_DISPLAY_PORTRAIT_90CCW)) {
disp_x = DispHeight;
disp_y = DispWidth;
}
if(*x_size > disp_x || *y_size > disp_y)
{
printf("LoadPng: Too big to fit on screen\n");
printf("LoadPng: PNG (%dx%d) does not fit on TFT (%dx%d)\n", *x_size, *y_size, DispWidth, DispHeight);
return (-3); // Too big to fit on screen
}
// printf("LoadPng: PNG (%dx%d) fits on TFT (%dx%d)\n", *x_size, *y_size, DispWidth, DispHeight);
// http://www.ftdichip.com/Support/Documents/AppNotes/AN_339%20Using%20JPEGs%20with%20the%20FT800%20series.pdf
// CMD_LOADIMAGE: This function will decode the JPEG file, produce
// either RGB565 or L8 bitmap data and store this in graphics RAM.
// It also writes commands to the display list to set the source, layout and size of the
// image (BITMAP_SOURCE, BITMAP_LAYOUT and BITMAP_SIZE).
// Note that only a BEGIN and VERTEX2F (or VERTEX2II) display list commands are then
// required to complete the display list needed to render the image.
WrCmd32(CMD_LOADIMAGE);
WrCmd32(_address); //destination address of png decode
// 0 OPT_RGB565
// 1 OPT_MONO
// 2 OPT_NODL
// 256 OPT_FLAT
// 256 OPT_SIGNED
// 512 OPT_CENTERX
// 1024 OPT_CENTERY
// 1536 OPT_CENTER
// 2048 OPT_RIGHTX
// 4096 OPT_NOBACK
// 8192 OPT_NOTICKS
// By default, option OPT_RGB565 means the loaded bitmap is in RGB565 format.
// Keep track of of the start addresses of loaded images
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
_address += (uint32_t) (size_x * size_y * 2);
_addresses[_bitmap_count] = _address;
printf("LoadPng: Bitmap# %d, Res. %dx%d, Address %d-%d\n", _bitmap_count - 1, *x_size, *y_size, _addresses[_bitmap_count-1], _addresses[_bitmap_count]);
WrCmd32(OPT_RGB565); // Output format of the bitmap OPT_RGB565
// unsigned int filesizeCounter = filesize;
char* pbuff = (char*)malloc(bufferSize);
while(filesize > 0) {
blocklen = filesize > bufferSize ? bufferSize : filesize;
int size = fread(pbuff, 1, blocklen, fp);
filesize -= blocklen;
WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
}
fclose(fp);
// If the number of bytes in the JPEG file to be written to the command buffer is not a multiple of
// four, then one, two or three bytes (of any value) should be added to ensure four-byte alignment of
// the next command.
// blocklen = filesize % 4;
// memset(pbuff, 0, blocklen);
// WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
free(pbuff);
printf("LoadPng: Done.\n");
return(0);
}
int FT813::LoadRaw(char* filename)
{
ft_uint16_t filesize = 0;
ft_uint16_t blocklen;
ft_uint16_t ram_start = _address;
int bufferSize = 8192;
FILE *fp = fopen(filename, "rb"); // open file
if (fp == NULL)
{
// Cannot open file
printf("Unable to open: %s\n", filename);
return -1;
}
fseek(fp, 0, SEEK_END); // set file position to end of file
filesize = ftell(fp); // determine file size
fseek(fp, 0, SEEK_SET); // return to beginning of file
// Keep track of of the start addresses of loaded images
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
_address += (uint32_t) filesize;
_addresses[_bitmap_count] = _address;
printf("LoadRaw: Bitmap# %d, Address %d-%d\n", _bitmap_count - 1, _addresses[_bitmap_count-1], _addresses[_bitmap_count]);
char* pbuff = (char*)malloc(bufferSize);
while(filesize > 0)
{
//copy the .raw file data to pbuff[8192] in 8k block
blocklen = filesize > bufferSize ? bufferSize : filesize;
fread(pbuff, 1, blocklen, fp);
filesize -= blocklen;
//write pbuff contents to graphics RAM at address ram_start = 0x00
Wr8s(ram_start, (uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
ram_start += blocklen;
}
fclose(fp);
free(pbuff);
return 0;
}
int FT813::LoadRawFile(ft_uint32_t address, const char *filename)
{
int bufferSize = 8192;
ft_uint32_t filesize = 0;
ft_uint16_t blocklen = 0;
_address = address;
ft_uint32_t addr = address;
FILE *fp = fopen(filename, "rb");
if (fp == NULL)
{
printf("LoadRawFile: Cannot open file \"%s\".\n", filename);
return 0;
}
fseek(fp, 0, SEEK_END); // End of file
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET); // Beginning of file
// Keep track of of the start addresses of loaded images
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
_address += (uint32_t) filesize;
_addresses[_bitmap_count] = _address;
printf("LoadRawFile: Bitmap# %d, Address %d-%d\n", _bitmap_count - 1, _addresses[_bitmap_count-1], _addresses[_bitmap_count]);
char* pbuff = (char*)malloc(bufferSize);
while (filesize > 0)
{
blocklen = filesize > bufferSize ? bufferSize : filesize;
fread(pbuff, 1, blocklen, fp);
filesize -= blocklen;
WrMem(addr, (ft_uint8_t *)pbuff, blocklen);
addr += blocklen;
// WrCmdBuf((ft_uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
}
fclose(fp);
free(pbuff);
printf("LoadRawFile: Done.\n");
return 1;
}
int FT813::LoadInflateFile(ft_uint32_t address, const char *filename)
{
int bufferSize = 8192;
ft_uint32_t filesize = 0;
ft_uint16_t blocklen = 0;
ft_uint32_t addr = address;
ft_uint32_t filesize_org = address;
_address = address;
FILE *fp = fopen(filename, "rb"); // read Binary (rb)
if (fp == NULL)
{
printf("LoadInflateFile: Cannot open file \"%s\".\n", filename);
return 0;
}
fseek(fp, 0, SEEK_END); // End of file
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET); // Beginning of file
// Keep track of of the start addresses of loaded images
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
// _address += (uint32_t) 0;
_addresses[_bitmap_count] = _address;
// printf("# %d, Addr %d\n", _bitmap_count - 1, _addresses[_bitmap_count-1]);
WrCmd32(CMD_INFLATE);
WrCmd32(address); //destination address of bin decode
char* pbuff = (char*)malloc(bufferSize);
while (filesize > 0)
{
blocklen = filesize > bufferSize ? bufferSize : filesize;
int size = fread(pbuff, 1, blocklen, fp); /* copy the data into pbuff and then transfter it to command buffer */
filesize -= blocklen;
// WrMem(addr, (ft_uint8_t *)pbuff, blocklen);
// addr += blocklen;
//Do not call "Ft_Gpu_Hal_WrCmdBuf_nowait" because it may cause emulator process hang.
WrCmdBuf((ft_uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
// WaitCmdfifo_empty();
}
// If the number of bytes in the JPEG file to be written to the command buffer is not a multiple of
// four, then one, two or three bytes (of any value) should be added to ensure four-byte alignment of
// the next command.
// blocklen = filesize_org % 4;
// memset(pbuff, 0, blocklen);
// WrMem(addr, (ft_uint8_t *)pbuff, blocklen);
// WrCmdBuf((uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
// WaitCmdfifo_empty();
fclose(fp); /* close the opened jpg file */
free(pbuff);
return 1;
}
int FT813::LoadImageFile(ft_uint32_t address, const char *filename)
{
int bufferSize = 8192;
ft_uint32_t filesize = 0;
ft_uint16_t blocklen = 0;
_address = address;
FILE *fp = fopen(filename, "rb"); // read Binary (rb)
if (fp == NULL)
{
printf("LoadImageFile: Cannot open file \"%s\".\n", filename);
return 0;
}
// TODO: Let it write into the scratch display list handle,
// and read it out and write into the bitmapInfo the proper
// values to use. Replace compressed bool with uint8 enum to
// specify the loading mechanism
fseek(fp, 0, SEEK_END); // End of file
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET); // Beginning of file
// Keep track of of the start addresses of loaded images
// Increment _address
_addresses[_bitmap_count] = _address;
_bitmap_count++;
_address += (uint32_t) filesize;
_addresses[_bitmap_count] = _address;
printf("LoadImageFile: Bitmap# %d, Address %d-%d\n", _bitmap_count - 1, _addresses[_bitmap_count-1], _addresses[_bitmap_count]);
WrCmd32(CMD_LOADIMAGE);
WrCmd32(address); //destination address of png decode
// 0 OPT_RGB565
// 1 OPT_MONO
// 2 OPT_NODL
// 256 OPT_FLAT
// 256 OPT_SIGNED
// 512 OPT_CENTERX
// 1024 OPT_CENTERY
// 1536 OPT_CENTER
// 2048 OPT_RIGHTX
// 4096 OPT_NOBACK
// 8192 OPT_NOTICKS
// By default, option OPT_RGB565 means the loaded bitmap is in RGB565 format.
WrCmd32(OPT_RGB565); // Output format of the bitmap OPT_RGB565
// WrCmd32(OPT_NODL);
char* pbuff = (char*)malloc(bufferSize);
while (filesize > 0)
{
blocklen = filesize > bufferSize ? bufferSize : filesize;
int size = fread(pbuff, 1, blocklen, fp); /* copy the data into pbuff and then transfter it to command buffer */
filesize -= blocklen;
// blocklen += 3;
// blocklen -= blocklen % 4;
//Do not call "Ft_Gpu_Hal_WrCmdBuf_nowait" because it may cause emulator process hang.
WrCmdBuf((ft_uint8_t *)pbuff, blocklen); //alignment is already taken care by this api
}
// WaitCmdfifo_empty();
fclose(fp); /* close the opened jpg file */
free(pbuff);
return 1;
}
ft_void_t FT813::SetEndAddressForSize(ft_uint32_t addr)
{
_addresses[_bitmap_count] = _addresses[_bitmap_count - 1] + addr;
}
ft_void_t FT813::Wr8s(ft_uint32_t addr, ft_uint8_t *buffer, ft_uint8_t length)
{
// StartTransfer(FT_GPU_WRITE, addr);
// if (FT_GPU_READ == rw) { // if (FT_GPU_READ == FT_GPU_WRITE)
// _ss = 0; // cs low
// _spi.write(addr >> 16);
// _spi.write(addr >> 8);
// _spi.write(addr & 0xff);
// _spi.write(0); //Dummy Read Byte
// status = READING;
// } else {
_ss = 0; // cs low
_spi.write(0x80 | (addr >> 16));
_spi.write(addr >> 8);
_spi.write(addr & 0xff);
status = WRITING;
// }
// Transfer8(v);
// _spi.write(v);
while (length--) {
// Transfer8(*buffer);
_spi.write(*buffer);
buffer++;
// SizeTransfered++;
}
// EndTransfer();
_ss = 1;
status = OPENED;
}
//{
//ft_uint8_t imbuff[8192];
//ft_uint16_t blocklen;
////decompress the .bin file using CMD_INFLATE
//WrCmd32(phost,CMD_INFLATE);
////specify starting address in graphics RAM
//WrCmd32(phost,0L);
////check filesize and adjust number of bytes to multiple of 4
//chdir("..\\..\\..\\Test"); //change directory to location (Test) of .bin file
//pfile = fopen("lenaface40.bin","rb");
//fseek(pfile,0,SEEK_END); //set file position to end of file
//filesize = ftell(pfile); // determine file size
//fseek(pfile,0,SEEK_SET); // return to beginning of file
//while(filesize > 0)
//{
// //copy the .raw file data to imbuff[8192] in 8k blocks
//blocklen = filesize>8192?8192:filesize;
//fread(imbuff,1,blocklen,pfile);
//filesize -= blocklen; //reduce filesize by blocklen
////write imbuff contents to the FT800 FIFO command buffer
//Ft_Gpu_Hal_WrCmdBuf(phost,imbuff,blocklen);
//}
//fclose(pfile); /* close the opened .bin file */
//}
int FT813::LoadRawFile(ft_uint32_t address, char* filename)
{
ft_uint16_t filesize;
ft_uint16_t blocklen;
ft_uint32_t addr = address;
int bufferSize = 8192;
FILE *fp = fopen(filename, "rb"); // open file
if (fp == NULL)
{
// Cannot open file
printf("Unable to open: %s\n", filename);
return -1;
}
fseek(fp, 0, SEEK_END); // set file position to end of file
filesize = ftell(fp); // determine file size
fseek(fp, 0, SEEK_SET); // return to beginning of file
#ifdef DEBUG
printf("LoadRawFile: %s %d @ %d\n", filename, filesize, address);
#endif
char* pbuff = (char*)malloc(bufferSize);
while(filesize > 0)
{
//copy the .raw file data to pbuff[8192] in 8k block
blocklen = filesize > bufferSize ? bufferSize : filesize;
fread(pbuff, 1, blocklen, fp);
filesize -= blocklen;
//write pbuff contents to graphics RAM at addr
WrMem(addr, (ft_uint8_t *)pbuff, blocklen);
addr += blocklen;
}
fclose(fp);
free(pbuff);
return 0;
}
void FT813::FillBitmap(ft_int16_t bitmap_number)
{
int bufferSize = 8192;
uint8_t* pbuff = (uint8_t*)malloc(bufferSize);
// Clear buffer
memset(pbuff, 0, bufferSize);
ft_int32_t addr_start = _addresses[bitmap_number];
ft_int32_t addr_end = _addresses[bitmap_number+1];
printf("FillBitmap %d (%d - %d).\n", bitmap_number, addr_start, addr_end);
// ft_int32_t bufferSize = addr_end - addr_start;
ft_int32_t filesize = addr_end - addr_start;
// ft_int32_t addr = addr_start;
WrCmd32(CMD_LOADIMAGE);
WrCmd32(addr_start); //destination address of png decode
WrCmd32(0); //output format of the bitmap - default is rgb565
printf("filesize = %d\n", filesize);
printf("while(filesize > 0)...\n");
while(filesize > 0) {
ft_uint16_t blocklen = filesize > bufferSize ? bufferSize : filesize;
// printf("WrCmdBuf %d.\n", bufferSize);
filesize -= blocklen;
printf("blocklen = %d\n", blocklen);
printf("WrCmdBuf...\n");
WrCmdBuf(pbuff, blocklen); //alignment is already taken care by this api
printf("Done.\n");
}
printf("free(pbuff)...\n");
free(pbuff);
printf("Done.\n");
}
void FT813::ClearBitmapCount(void)
{
_bitmap_count = 0;
}
ft_uint32_t FT813::ReadBigInt32(unsigned char* data, ft_uint32_t offset)
{
return (data[offset + 0] << 24 | data[24 - 4 + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]);
}
// Loads JPG at x, y on the screen
ft_uint8_t FT813::Jpg(char *jpg_filename, int x, int y)
{
ft_int16_t x_size,y_size;
int err;
err = LoadJpg(jpg_filename, & x_size, & y_size); // load graphic data into buffer and decode jpg to bitmap
if(err != 0) { // something is wrong - display error
printf("LoadJpg: Error.\n");
return(-1);
}
DL(BEGIN(BITMAPS));
// LoadIdentity();
// SetMatrix();
DL(VERTEX2F(x * 16, y * 16));
// jpg is loaded and decoded into bitmap
// printf("jpg %s is loaded and decoded into bitmap (%dx%d)\n", jpg_filename, x_size, y_size);
return(0);
}
// Loads PNG at x, y on the screen
ft_uint8_t FT813::Png(char *png_filename, int x, int y)
{
ft_int16_t x_size,y_size;
int err;
err = LoadPng(png_filename, & x_size, & y_size); // load graphic data into buffer and decode png to bitmap
if(err != 0) { // something is wrong - display error
printf("LoadPng: Error.\n");
return(-1);
}
DL(BEGIN(BITMAPS));
// LoadIdentity();
// SetMatrix();
DL(VERTEX2F(x * 16, y * 16));
// png is loaded and decoded into bitmap
// printf("png %s is loaded and decoded into bitmap (%dx%d)\n", png_filename, x_size, y_size);
return(0);
}
// Loads PNG at x, y on the screen at given address
ft_uint8_t FT813::Png(char *png_filename, int x, int y, ft_int32_t address)
{
ft_int16_t x_size,y_size;
int err;
_address = address;
err = LoadPng(png_filename, & x_size, & y_size); // load graphic data into buffer and decode png to bitmap
if(err != 0) { // something is wrong - display error
printf("LoadPng: Error.\n");
return(-1);
}
DL(BEGIN(BITMAPS));
// LoadIdentity();
// SetMatrix();
DL(VERTEX2F(x * 16, y * 16));
// DL(DISPLAY()); //ends the display,commands after this ignored
// png is loaded and decoded into bitmap
printf("png %s is loaded and decoded into bitmap (%dx%d)\n", png_filename, x_size, y_size);
return(0);
}
// Loads JPG at the center of the screen (splash screen)
// Background color specified
ft_uint8_t FT813::JpgSplash(char *jpg_filename, ft_uint8_t r, ft_uint8_t g, ft_uint8_t b)
{
ft_int16_t x_size,y_size;
int err;
DLstart(); // start a new display command list
DL(CLEAR_COLOR_RGB(r, g, b)); // set the clear color to white
DL(CLEAR(1, 1, 1)); // clear buffers -> color buffer,stencil buffer, tag buffer
err = LoadJpg(jpg_filename, & x_size, & y_size); // load graphic data into buffer and decode jpg to bitmap
if(err != 0) { // something is wrong - display error
printf("LoadJpg: Error.\n");
return(-1);
}
DL(BEGIN(BITMAPS));
LoadIdentity();
SetMatrix();
int x = (DispWidth - x_size) / 2;
int y = (DispHeight - y_size) / 2;
DL(VERTEX2F(x * 16, y * 16));
DL(DISPLAY()); // Display the image
Swap(); // Swap the current display list
Flush_Co_Buffer(); // Download the command list into fifo
WaitCmdfifo_empty(); // Wait till coprocessor completes the operation
return(0);
}
// ***************************************************************************************************************
// *** Utility and helper functions ******************************************************************************
// ***************************************************************************************************************
// Find the space available in the GPU AKA CoProcessor AKA command buffer AKA FIFO
ft_uint16_t FT813::CoProFIFO_FreeSpace(void)
{
ft_uint16_t cmdBufferDiff, cmdBufferRd, cmdBufferWr, retval;
cmdBufferRd = Rd16(REG_CMD_READ + RAM_REG);
cmdBufferWr = Rd16(REG_CMD_WRITE + RAM_REG);
cmdBufferDiff = (cmdBufferWr-cmdBufferRd) % FT_CMD_FIFO_SIZE; // FT81x Programmers Guide 5.1.1
retval = (FT_CMD_FIFO_SIZE - 4) - cmdBufferDiff;
return (retval);
}
// Sit and wait until there are the specified number of bytes free in the <GPU/CoProcessor> incoming FIFO
void FT813::Wait4CoProFIFO(ft_uint32_t room)
{
ft_uint16_t getfreespace;
do {
getfreespace = CoProFIFO_FreeSpace();
} while(getfreespace < room);
}
// Sit and wait until the CoPro FIFO is empty
void FT813::Wait4CoProFIFOEmpty(void)
{
while(Rd16(REG_CMD_READ + RAM_REG) != Rd16(REG_CMD_WRITE + RAM_REG));
}
// Check if the CoPro FIFO is empty
// returns 1 if the CoPro FIFO is empty
// returns 0 if the CoPro FIFO is not empty
ft_uint8_t FT813::CheckIfCoProFIFOEmpty(void)
{
return (Rd16(REG_CMD_READ + RAM_REG) == Rd16(REG_CMD_WRITE + RAM_REG)) ? 1 : 0;
}
// Write a block of data into Eve RAM space a byte at a time.
// Return the last written address + 1 (The next available RAM address)
ft_uint32_t FT813::WriteBlockRAM(ft_uint32_t Add, const ft_uint8_t *buff, ft_uint32_t count)
{
ft_uint32_t index;
ft_uint32_t WriteAddress = Add; // I want to return the value instead of modifying the variable in place
for (index = 0; index < count; index++) {
Wr8(WriteAddress++, buff[index]);
}
return (WriteAddress);
}
/* function to load jpg file from filesystem */
/* return 0 if jpg is ok */
/* return x_size and y_size of jpg */
//int FT813::Load_jpg(char* filename, ft_int16_t* x_size, ft_int16_t* y_size, ft_uint32_t address)
//{
// unsigned char pbuff[8192];
// unsigned short marker;
// unsigned short length;
// unsigned char data[4];
//
// ft_uint16_t blocklen;
//// sd.mount();
// FILE *fp = fopen(filename, "r");
// if(fp == NULL) return (-1); // connot open file
//
// // search for 0xFFC0 marker
// fseek(fp, 0, SEEK_END);
// unsigned int filesize = ftell(fp);
// fseek(fp, 2, SEEK_SET);
// fread(data,4,1,fp);
// marker = data[0] << 8 | data[1];
// length = data[2] << 8 | data[3];
// do {
// if(marker == 0xFFC0) break;
// if(marker & 0xFF00 != 0xFF00) break;
// if (fseek(fp, length - 2,SEEK_CUR) != 0) break;
// fread(data,4,1,fp);
// marker = data[0] << 8 | data[1];
// length = data[2] << 8 | data[3];
// } while(1);
// if(marker != 0xFFC0) return (-2); // no FFC0 Marker, wrong format no baseline DCT-based JPEG
// fseek(fp, 1,SEEK_CUR);
// fread(data,4,1,fp);
// *y_size = (data[0] << 8 | data[1]);
// *x_size = (data[2] << 8 | data[3]);
//
// //if(*x_size > DispWidth || *y_size > DispHeight) return (-3); // to big to fit on screen
//
// fseek(fp, 0, SEEK_SET);
// WrCmd32(CMD_LOADIMAGE); // load a JPEG image
// WrCmd32(address); //destination address of jpg decode
// WrCmd32(0); //output format of the bitmap - default is rgb565
// while(filesize > 0) {
// /* download the data into the command buffer by 8kb one shot */
// blocklen = filesize>8192?8192:filesize;
// /* copy the data into pbuff and then transfter it to command buffer */
// fread(pbuff,1,blocklen,fp);
// filesize -= blocklen;
// /* copy data continuously into command memory */
// WrCmdBuf(pbuff, blocklen); //alignment is already taken care by this api
// }
// fclose(fp);
//// sd.unmount();
//
// return(0);
//}
//int FT813::Load_raw(char* filename)
//{
// ft_uint8_t imbuff[8192];
// ft_uint16_t filesize;
// ft_uint16_t blocklen;
//// ft_uint16_t ram_start = 0x00;
//
//// sd.mount();
// FILE *fp = fopen(filename, "rb"); // open file
//// if(fp == NULL) return (-1); // connot open file
// fseek(fp, 0, SEEK_END); // set file position to end of file
// filesize= ftell(fp); // determine file size
// fseek(fp, 2, SEEK_SET); // return to beginning of file
//
// while(filesize > 0)
// {
// //copy the .raw file data to imbuff[8192] in 8k block
// blocklen = filesize>8192?8192:filesize;
// fread(imbuff,1,blocklen,fp);
// filesize-= blocklen;
// //write imbuff contents to graphics RAM at address ram_start = 0x00
// WrCmdBuf(imbuff, blocklen); //alignment is already taken care by this api
//// ram_start += 8192;
// }
// fclose(fp);
//// sd.unmount();
//
// return 0;
//}
/* calibrate touch */
ft_void_t FT813::Calibrate()
{
/*************************************************************************/
/* Below code demonstrates the usage of calibrate function. Calibrate */
/* function will wait untill user presses all the three dots. Only way to*/
/* come out of this api is to reset the coprocessor bit. */
/*************************************************************************/
DLstart(); // start a new display command list
DL(CLEAR_COLOR_RGB(64,64,64)); // set the clear color R, G, B
DL(CLEAR(1,1,1)); // clear buffers -> color buffer,stencil buffer, tag buffer
DL(COLOR_RGB(0xff,0xff,0xff)); // set the current color R, G, B
Text((DispWidth/2), (DispHeight/2), 27, OPT_CENTER, "Please tap on the dot"); // draw Text at x,y, font 27, centered
Calibrate(0); // start the calibration of touch screen
Flush_Co_Buffer(); // download the commands into FT813 FIFO
WaitCmdfifo_empty(); // Wait till coprocessor completes the operation
}
/* API to give fadeout effect by changing the display PWM from 100 till 0 */
ft_void_t FT813::fadeout()
{
ft_int32_t i;
for (i = 100; i >= 0; i -= 3)
{
Wr8(REG_PWM_DUTY, i);
Sleep(2);//sleep for 2 ms
}
}
/* API to perform display fadein effect by changing the display PWM from 0 till 100 and finally 128 */
ft_void_t FT813::fadein()
{
ft_int32_t i;
for (i = 0; i <=100 ; i += 3)
{
Wr8(REG_PWM_DUTY,i);
Sleep(2);//sleep for 2 ms
}
/* Finally make the PWM 100% */
i = 128;
Wr8(REG_PWM_DUTY,i);
}
ft_uint8_t FT813::read_calibrate_reg(ft_uint8_t i) {
return Rd8(REG_TOUCH_TRANSFORM_A + i);
}
ft_uint32_t FT813::read_calibrate_reg32(ft_uint8_t i) {
return (Rd8(REG_TOUCH_TRANSFORM_A + i)) + // lsb
(Rd8(REG_TOUCH_TRANSFORM_A + i+1) << 8) +
(Rd8(REG_TOUCH_TRANSFORM_A + i+2) << 16) +
(Rd8(REG_TOUCH_TRANSFORM_A + i+3) << 24); // msb
}
ft_void_t FT813::read_calibrate(ft_uint8_t data[24]) {
unsigned int i;
for(i = 0; i < 24; i++) {
data[i] = Rd8(REG_TOUCH_TRANSFORM_A + i);
}
}
ft_void_t FT813::write_calibrate(ft_uint8_t data[24]) {
unsigned int i;
for(i = 0; i < 24; i++) {
Wr8(REG_TOUCH_TRANSFORM_A + i, data[i]);
}
}
ft_void_t FT813::write_calibrate32(ft_uint32_t data[6]) {
unsigned int i;
for(i = 0; i < 6; i++) {
Wr8(REG_TOUCH_TRANSFORM_A + i*4, (data[i]) & 0xff); // lsb
Wr8(REG_TOUCH_TRANSFORM_A + i*4 + 1, (data[i] >> 8) & 0xff);
Wr8(REG_TOUCH_TRANSFORM_A + i*4 + 2, (data[i] >> 16) & 0xff);
Wr8(REG_TOUCH_TRANSFORM_A + i*4 + 3, (data[i] >> 24) & 0xff); // msb
}
}
ft_uint32_t FT813::color_rgb(ft_uint8_t red, ft_uint8_t green, ft_uint8_t blue){
return ((4UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0));
}
ft_uint32_t FT813::clear_color_rgb(ft_uint8_t red, ft_uint8_t green, ft_uint8_t blue){
return ((2UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0));
}
// Define the backlight PWM output duty cycle.
void FT813::SetBacklight(ft_uint16_t brightness)
{
brightness = brightness * brightness / 255;
if (brightness > 256)
brightness = 256;
if (brightness < 16)
brightness = 16;
Wr16(REG_PWM_DUTY, brightness); // Brightness
}
void FT813::Tag(ft_uint8_t tag)
{
DL(TAG(tag));
}
void FT813::ClearTag(ft_uint8_t tag)
{
DL(CLEAR_TAG(tag));
}
void FT813::TagMask(ft_uint8_t mask)
{
DL(TAG_MASK(mask));
}
void FT813::BitmapLayoutH(ft_uint8_t linestride, ft_uint8_t height)
{
DL((40 << 24) | (((linestride) & 3) << 2) | (((height) & 3) << 0));
}
void FT813::BitmapSizeH(ft_uint8_t width, ft_uint8_t height)
{
DL((41UL << 24) | (((width) & 3) << 2) | (((height) & 3) << 0));
}
ft_void_t FT813::SetLoadAddress(ft_uint32_t address)
{
_address = address; // Old, try to get rid of this
_bitmapAddress = address;
}
ft_void_t FT813::SetBitmapCount(ft_uint8_t count)
{
_bitmap_count = count; // Old, try to get rid of this
_bitmapCount = count;
}
ft_uint32_t FT813::GetBitmapAddress(ft_uint8_t bitmap_number)
{
return _addresses[bitmap_number];
}
void FT813::SetThemeDefaultColor(void)
{
// Default
GradColor(COLOR_RGB(0xff, 0xff, 0xff)); // Default 0xffffff
FgColor(COLOR_RGB(0x00, 0x38, 0x70)); // Default 0x003870 (0, 56, 112)
BgColor(COLOR_RGB(0x00, 0x20, 0x40)); // Default 0x002040 (0, 32, 64)
}
void FT813::SetThemeColor(ft_uint32_t c)
{
GradColor(COLOR_RGB(0xff, 0xff, 0xff)); // Default 0xffffff
ft_uint8_t r = (c >> 16) & 0xff;
ft_uint8_t g = (c >> 8) & 0xff;
ft_uint8_t b = c & 0xff;
ft_uint8_t rfg = r * 112 / 255;
ft_uint8_t gfg = g * 112 / 255;
ft_uint8_t bfg = b * 112 / 255;
ft_uint8_t rbg = r * 64 / 255;
ft_uint8_t gbg = g * 64 / 255;
ft_uint8_t bbg = b * 64 / 255;
FgColor(COLOR_RGB(rfg, gfg, bfg)); // Default 0x003870
BgColor(COLOR_RGB(rbg, gbg, bbg)); // Default 0x002040
}
// ShowCalibration
void FT813::ShowCalibrationInCode(void)
{
// Read calibrate registers
printf("// Calibration values:\n");
printf(" ft_uint32_t canned_calibration_data[] = {\n");
for(int i = 0; i < 24; i+=4) {
printf(" ");
printf("0x%08x", read_calibrate_reg32(i));
if (i < 20)
printf(",");
printf("\n");
}
printf(" };\n");
printf(" write_calibrate32(canned_calibration_data);\n");
}
// Set screen orientation and preload canned touch screen calibration values
void FT813::SetOrientation(ft_uint8_t orientation)
{
// TFT.SetRotate(0); // Standard landscape
// TFT.SetRotate(1); // Rotate 180 to landscape (upside down)
// TFT.SetRotate(2); // Rotate 90 CCW to portrait
// TFT.SetRotate(3); // Rotate 90 CW to portrait
// TFT.SetRotate(4); // Mirror over landscape X
// TFT.SetRotate(5); // Mirror over landscape Y
// TFT.SetRotate(6); // Rotate 90 CCW to portrait and mirror over portrait X
// TFT.SetRotate(7); // Rotate 90 CW to portrait and mirror over portrait X
_orientation = orientation;
SetRotate(orientation); // Standard landscape
// Canned calibration for the orientation
if (orientation == FT8_DISPLAY_LANDSCAPE_0)
{
// Landscape 0
ft_uint32_t canned_calibration_data[] = {
0x000109b0, // 68016
0x0000023d, // 573
0x0000fa64, // 64100
0xffffffcf, // -49
0xfffefc9a, // -66406
0x01ee8754 // 32409428
};
write_calibrate32(canned_calibration_data);
}
if (orientation == FT8_DISPLAY_PORTRAIT_90CW)
{
ft_uint32_t canned_calibration_data[] = {
0xfffff994,
0xffff07d3,
0x01e4b85c,
0xfffef6f5,
0x000002ad,
0x032eb4d4
};
write_calibrate32(canned_calibration_data);
}
if (orientation == FT8_DISPLAY_PORTRAIT_90CCW)
{
// Calibration rotate 90 CCW to portrait
ft_uint32_t canned_calibration_data[] = {
0x00000491,
0x0000fd0b,
0xfff6f84b,
0x00010503,
0x000006b7,
0xffeeb0b7
};
write_calibrate32(canned_calibration_data);
}
}
void FT813::ShowBitmap(ft_uint8_t bitmap, ft_int16_t fmt, ft_uint16_t x, ft_uint16_t y, ft_uint16_t width, ft_uint16_t height)
{
ft_int32_t addr = GetBitmapAddress(bitmap);
DL(BITMAP_SOURCE(addr));
// ft_int16_t stride = width * 2;
// 1-bits/p L1
// if (fmt == L1) {
// stride = width / 8;
// }
// 2-bits/p L2
// if (fmt == L2) {
// stride = width / 4;
// }
// 4-bits/p L4
// if (fmt == L4) {
// stride = width / 2;
// }
// 8-bits/p L8 RGB332 ARGB2 PALETTED565 PALETTED4444 PALETTED8
// if ((fmt == L8) ||
// (fmt == RGB332) ||
// (fmt == ARGB2) ||
// (fmt == PALETTED565) ||
// (fmt == PALETTED4444) ||
// (fmt == PALETTED8)) {
// stride = width;
// }
// 16-bits/p ARGB1555 ARGB4 RGB565
// if ((fmt == ARGB1555) ||
// (fmt == ARGB4) ||
// (fmt == RGB565)) {
// stride = width * 2;
// }
// DL(BITMAP_LAYOUT(fmt, stride, h)); // 10-bit linestride, 9-bit height
// DL(BITMAP_LAYOUT_H(stride >> 10, h >> 9)); // msb bits
// DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, w, h)); // 9-bit width, 9-bit height
// DL(BITMAP_SIZE_H(w >> 9, h >> 9)); // msb bits
SetBitmap(addr, fmt, width, height);
// DL(VERTEX2II(x, y, 0, 0));
DL(VERTEX2F(x * 16, y * 16));
}
void FT813::ShowBitmapAtAddress(ft_uint32_t addr, ft_int16_t fmt, ft_uint16_t x, ft_uint16_t y, ft_uint16_t width, ft_uint16_t height)
{
DL(BITMAP_SOURCE(addr));
// ft_int16_t stride = width * 2;
// 1-bits/p L1
// if (fmt == L1) {
// stride = width / 8;
// }
// 2-bits/p L2
// if (fmt == L2) {
// stride = width / 4;
// }
// 4-bits/p L4
// if (fmt == L4) {
// stride = width / 2;
// }
// 8-bits/p L8 RGB332 ARGB2 PALETTED565 PALETTED4444 PALETTED8
// if ((fmt == L8) ||
// (fmt == RGB332) ||
// (fmt == ARGB2) ||
// (fmt == PALETTED565) ||
// (fmt == PALETTED4444) ||
// (fmt == PALETTED8)) {
// stride = width;
// }
// 16-bits/p ARGB1555 ARGB4 RGB565
// if ((fmt == ARGB1555) ||
// (fmt == ARGB4) ||
// (fmt == RGB565)) {
// stride = width * 2;
// }
// DL(BITMAP_LAYOUT(fmt, stride, h)); // 10-bit linestride, 9-bit height
// DL(BITMAP_LAYOUT_H(stride >> 10, h >> 9)); // msb bits
// DL(BITMAP_SIZE(NEAREST, BORDER, BORDER, w, h)); // 9-bit width, 9-bit height
// DL(BITMAP_SIZE_H(w >> 9, h >> 9)); // msb bits
SetBitmap(addr, fmt, width, height);
// DL(VERTEX2II(x, y, 0, 0));
DL(VERTEX2F(x * 16, y * 16));
}
int FT813::GetImageIndexFromName(char *name)
{
for (int i = 0; i < _bitmapCount; i++) {
if(strstr(_bitmaps[i].name, name) != NULL) {
return i;
}
}
return -1;
}
int FT813::ResetInflateFileBitmap(void)
{
_bitmapAddress = 0;
_bitmapCount = 0;
}
uint32_t FT813::GetRamUsage(void)
{
return _bitmapAddress;
}
uint16_t FT813::GetRamNoOfBitmaps(void)
{
return _bitmapCount;
}
int FT813::LoadInflateFileBitmap(char *name, uint16_t fmt, uint16_t w, uint16_t h)
{
strcpy(_bitmaps[_bitmapCount].name, name);
_bitmaps[_bitmapCount].fmt = fmt;
_bitmaps[_bitmapCount].w = w;
_bitmaps[_bitmapCount].h = h;
_bitmaps[_bitmapCount].addr = _bitmapAddress;
// 1-bits/p L1
if (_bitmaps[_bitmapCount].fmt == L1) {
_bitmaps[_bitmapCount].size = _bitmaps[_bitmapCount].w * _bitmaps[_bitmapCount].h / 8;
}
// 2-bits/p L2
if (_bitmaps[_bitmapCount].fmt == L2) {
_bitmaps[_bitmapCount].size = _bitmaps[_bitmapCount].w * _bitmaps[_bitmapCount].h / 4;
}
// 4-bits/p L4
if (_bitmaps[_bitmapCount].fmt == L4) {
_bitmaps[_bitmapCount].size = _bitmaps[_bitmapCount].w * _bitmaps[_bitmapCount].h / 2;
}
// 8-bits/p L8 RGB332 ARGB2 PALETTED565 PALETTED4444 PALETTED8
if ((_bitmaps[_bitmapCount].fmt == L8) ||
(_bitmaps[_bitmapCount].fmt == RGB332) ||
(_bitmaps[_bitmapCount].fmt == ARGB2) ||
(_bitmaps[_bitmapCount].fmt == PALETTED565) ||
(_bitmaps[_bitmapCount].fmt == PALETTED4444) ||
(_bitmaps[_bitmapCount].fmt == PALETTED8)) {
_bitmaps[_bitmapCount].size = _bitmaps[_bitmapCount].w * _bitmaps[_bitmapCount].h;
}
// 16-bits/p ARGB1555 ARGB4 RGB565
if ((_bitmaps[_bitmapCount].fmt == ARGB1555) ||
(_bitmaps[_bitmapCount].fmt == ARGB4) ||
(_bitmaps[_bitmapCount].fmt == RGB565)) {
_bitmaps[_bitmapCount].size = _bitmaps[_bitmapCount].w * _bitmaps[_bitmapCount].h * 2;
}
LoadInflateFile(_bitmaps[_bitmapCount].addr, _bitmaps[_bitmapCount].name); // x 0, y 0, w 32, h 32, size 1024
_bitmapAddress += _bitmaps[_bitmapCount].size;
_bitmapCount++;
}
int FT813::ShowBitmapByName(char *name, uint16_t x, uint16_t y)
{
int index = GetImageIndexFromName(name);
ShowBitmapAtAddress(_bitmaps[index].addr, _bitmaps[index].fmt, x, y, _bitmaps[index].w, _bitmaps[index].h);
}
uint16_t FT813::GetTouchedTag(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TrackRegisterVal = Rd32(REG_TRACKER); // check if one of the tracking fields is touched
return TrackRegisterVal & 0xffff;
}
uint16_t FT813::GetTouchedTag(uint8_t point_number)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
// check if one of the tracking fields is touched
uint32_t TrackRegisterVal = 0;
switch (point_number) {
case 0:
TrackRegisterVal = Rd32(REG_TRACKER); // First point
break;
case 1:
TrackRegisterVal = Rd32(REG_TRACKER_1); // Second point
break;
case 2:
TrackRegisterVal = Rd32(REG_TRACKER_2); // Third point
break;
case 3:
TrackRegisterVal = Rd32(REG_TRACKER_3); // Fourth point
break;
case 4:
TrackRegisterVal = Rd32(REG_TRACKER_4); // Fift point
break;
}
return TrackRegisterVal & 0xffff;
}
uint8_t FT813::GetTag(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TagRegisterVal = Rd32(REG_TAG); // check if one of the tracking fields is touched
return TagRegisterVal & 0xff;
}
uint16_t FT813::GetTagX(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TagRegisterVal = Rd32(REG_TAG_X); // check if one of the tracking fields is touched
return TagRegisterVal & 0x7ff;
}
uint16_t FT813::GetTagY(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TagRegisterVal = Rd32(REG_TAG_Y); // check if one of the tracking fields is touched
return TagRegisterVal & 0x7ff;
}
uint8_t FT813::GetTouchTag(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TagRegisterVal = Rd32(REG_TOUCH_TAG); // check if one of the tracking fields is touched
return TagRegisterVal & 0xff;
}
uint16_t FT813::GetTouchTagX(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TagRegisterVal = Rd32(REG_TOUCH_TAG_XY); // check if one of the tracking fields is touched
return (TagRegisterVal >> 16) & 0xffff;
}
uint16_t FT813::GetTouchTagY(void)
{
// REG_TOUCH_TAG
// If the screen is being touched, the screen coordinates are looked up in the screen's tag buffer,
// delivering a final 8-bit tag value, in REG_TOUCH_TAG.
// REG_TOUCH_TAG_XY
// Because the tag lookup takes a full frame, and touch coordinates change continuously,
// the original (x; y) used for the tag lookup is also available in REG_TOUCH_TAG_XY.
uint32_t TagRegisterVal = Rd32(REG_TOUCH_TAG_XY); // check if one of the tracking fields is touched
return TagRegisterVal & 0xffff;
}
uint16_t FT813::GetTouchConfig(void)
{
// Read 0x0381
// 0000 0011 1000 0001
// bit 15 0: capacitive, 1: resistive
// bit 10 - 4: I2C address of touch screen module: 0x011 1000 0x38
// bit 3: 0: FocalTech, 1: Azoteq
// bit 1 - 0: sampler clocks 0x01
uint32_t TouchConfigVal = Rd32(REG_TOUCH_CONFIG); // check if one of the tracking fields is touched
return TouchConfigVal & 0xffff;
}
void FT813::SetTouchConfig(uint16_t TouchConfigVal = VAL_TOUCH_CONFIG)
{
Wr32(REG_TOUCH_CONFIG, (uint32_t) TouchConfigVal);
}
void FT813::screenShot(void)
{
int bufferSize = 800*480;
char* pbuff = (char*)malloc(bufferSize);
// wr8(REG_SCREENSHOT_EN, 1);
// for (int ly = 0; ly < SCREEN_HEIGHT; ly++) {
// wr16(REG_SCREENSHOT_Y, ly);
// wr8(REG_SCREENSHOT_START, 1);
//
// //Read 64 bit registers to see if it is busy
// while (rd32(REG_SCREENSHOT_BUSY) | rd32(REG_SCREENSHOT_BUSY + 4));
//
// wr8(REG_SCREENSHOT_READ , 1);
// for (int lx = 0; lx < SCREEN_WIDTH; lx ++) {
// //Read 32 bit pixel value from RAM_SCREENSHOT
// //The pixel format is BGRA: Blue is in lowest address and Alpha
// is in highest address
// screenshot[ly*SCREEN_HEIGHT + lx] = rd32(RAM_SCREENSHOT + lx*4);
// }
// wr8(REG_SCREENSHOT_READ, 0);
// }
// wr8(REG_SCREENSHOT_EN, 0);
free(pbuff);
}