808
Dependents: Chromatograph_Mobile
Diff: src/FT_Hal_Utils.cpp
- Revision:
- 10:6a81aeca25e3
- Parent:
- 5:506e2de9a9e6
- Child:
- 13:5959af2ac87a
diff -r ca6a7c6a2f4b -r 6a81aeca25e3 src/FT_Hal_Utils.cpp --- a/src/FT_Hal_Utils.cpp Thu Dec 22 20:19:22 2016 +0000 +++ b/src/FT_Hal_Utils.cpp Mon Jul 23 12:22:23 2018 +0000 @@ -2,65 +2,891 @@ #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 FT800::Load_jpg(char* filename, ft_int16_t* x_size, ft_int16_t* y_size, ft_uint32_t address) -{ - unsigned char pbuff[8291]; - 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 +//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); +//} - // search for 0xFFC0 marker - fseek(fp, 0, SEEK_END); - unsigned int Fsize = 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(Fsize > 0) { - /* download the data into the command buffer by 8kb one shot */ - blocklen = Fsize>8192?8192:Fsize; - /* copy the data into pbuff and then transfter it to command buffer */ - fread(pbuff,1,blocklen,fp); - Fsize -= 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 FT800::Load_raw(char* filename) +//int FT813::Load_raw(char* filename) //{ // ft_uint8_t imbuff[8192]; // ft_uint16_t filesize; @@ -90,47 +916,39 @@ // return 0; //} - - - - - /* calibrate touch */ -ft_void_t FT800::Calibrate() +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 FT800 FIFO - WaitCmdfifo_empty(); // Wait till coprocessor completes the operation - } + 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 FT800::fadeout() +ft_void_t FT813::fadeout() { - ft_int32_t i; + ft_int32_t i; for (i = 100; i >= 0; i -= 3) { - Wr8(REG_PWM_DUTY,i); + 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 FT800::fadein() +ft_void_t FT813::fadein() { ft_int32_t i; @@ -144,25 +962,516 @@ Wr8(REG_PWM_DUTY,i); } -ft_void_t FT800::read_calibrate(ft_uint8_t data[24]){ +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<24;i++){ - data[i] = Rd8(REG_TOUCH_TRANSFORM_A + 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)); } -ft_void_t FT800::write_calibrate(ft_uint8_t data[24]){ - unsigned int i; - for(i=0;i<24;i++) { - Wr8(REG_TOUCH_TRANSFORM_A + i,data[i]); +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; } -ft_uint32_t FT800::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)); +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); -ft_uint32_t FT800::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)); - } - \ No newline at end of file +// 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); +} \ No newline at end of file