808
Dependents: Chromatograph_Mobile
src/FT_Hal_Utils.cpp
- Committer:
- nikmaos
- Date:
- 2020-09-01
- Revision:
- 13:5959af2ac87a
- Parent:
- 10:6a81aeca25e3
File content as of revision 13:5959af2ac87a:
#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_SCREEN_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; } uint32_t FT813::GetTouchTagXY(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. return Rd32(REG_TOUCH_SCREEN_XY); // check if one of the tracking fields is touched } 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); }