4D systems Picaso uLCD 32PTU touch display library

Picaso_4DGL-32PTU_File.cpp

Committer:
CaptainR
Date:
2016-09-29
Revision:
27:dbf79d116497
Parent:
26:c6a803706a42

File content as of revision 27:dbf79d116497:

//
//  Picaso_4DGL-32PTU is a class to drive 4D Systems TFT touch screens with PICASO processor
//  Tested with NUCLEO L152RE development board
//  Copyright (C) <2016> Rihards Balass <rihards.balass@gmail.com>
//
// Picaso_4DGL-32PTU is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Picaso_4DGL-32PTU is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You can see GNU General Public License at <http://www.gnu.org/licenses/>.
//

#include "mbed.h"
#include "Picaso_4DGL-32PTU.h"

//**************************************************************************
// Starts up the FAT16 disk file services and allocates a small 32 byte control block
// for subsequent use. When you open a file using the “File Open” command
// further 512 + 44 = 556 bytes are attached to the FAT16 file control block.
// When you close a file using the “File Close” command, the 556 byte allocation
// is released leaving the 32 byte file control block.
// The File Mount command must be called before any other FAT16 file related
// functions can be used. The control block and all FAT16 file resources are
// completely released with the “File Unmount” command.
//**************************************************************************
bool PICASO_4DGL :: file_Mount() {

    char command[2] = "";
    
    command[0] = (FILE_MOUNT >> (8*1)) & 0xff;
    command[1] = (FILE_MOUNT >> (8*0)) & 0xff;
    
    writeCOMMAND(command, 2);
    bool success = fileMountResponse();
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: FAT16 Mount: %s\n\r", success ? "true" : "false");
#endif
    return success;
}

//**************************************************************************
// Returns the most recent error code or 0 if there were no errors.
// Returns Error Number.
// 1    IDE command execution error
// 2    CARD not present
// 3    WRONG partition type, not FAT16
// 4    MBR sector invalid signature
// 5    Boot Record invalid signature
// 6    Media not mounted
// 7    File not found in open for read
// 8    File not open
// 9    Fat attempt to read beyond EOF
// 10   Reached the end of file
// 11   Invalid cluster value > maxcls
// 12   All root dir entry are taken
// 13   All clusters in partition are taken
// 14   A file with same name exist already
// 15   Cannot init the CARD
// 16   Cannot read the MBR
// 17   Malloc could not allocate the FILE struct
// 18   Mode was not r.w.
// 19   Failure during FILE search
// 20   Invalid Filename
// 21   bad media
// 22   Sector Read fail
// 23   Sector write fail
// 26   File is empty (size 0)
//**************************************************************************
short PICASO_4DGL :: file_Error() {

    char command[2] = "";
    
    command[0] = (FILE_ERROR >> (8*1)) & 0xff;
    command[1] = (FILE_ERROR >> (8*0)) & 0xff;
    
    writeCOMMAND(command, 2);
    short error = fileErrorResponse();
#ifdef DEBUGMODE
    //pc.printf("\n\r DEBUG: FAT16 Error: %i\n\r", error);
#endif
    return error;
}

//**************************************************************************
// Returns number of files found that match the criteria.
// The wild card character '*' matches up with any combination of allowable
// characters and '?' matches up with any single allowable character.
//**************************************************************************
short PICASO_4DGL :: file_Count(char *filename) {
    
    int size = 3 + strlen(filename);
    int i, k, j = 2;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_COUNT >> (8*1)) & 0xff;
    command[1] = (FILE_COUNT >> (8*0)) & 0xff;
    for (k = 0; k < size-1; k++) command[j++] = filename[k];
    command[j] = 0;
    
    writeCOMMAND(command, size);
    short success = fileCountResponse();
    free(command);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: %s count = %i\n\r", filename, success);
#endif
    return success;
}

//**************************************************************************
// Lists the stream of file names that agree with the search key on the Display Screen.
// Returns number of files found that match the criteria.
// The wild card character '*' matches up with any combination of allowable characters
// and '?' matches up with any single allowable character.
// 
// Note: “Find First File and Report” and “Find Next File and Report” are
// recommended alternatives in order to return the responses.
//**************************************************************************
short PICASO_4DGL :: file_Dir(char *filename) {
    
    int size = 3 + strlen(filename);
    int i, k, j = 2;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_DIR >> (8*1)) & 0xff;
    command[1] = (FILE_DIR >> (8*0)) & 0xff;
    for (k = 0; k < size-1; k++) command[j++] = filename[k];
    command[j] = 0;
    
    writeCOMMAND(command, size);
    short success = fileCountResponse();
    free(command);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: %s count = %i\n\r", filename, success);
#endif
    return success;
}

//**************************************************************************
// Returns true if at least 1 file exists that satisfies the file argument.
// Wildcards are usually used so if the “Find First File” command returns true,
// further tests can be made using the “Find Next File” command to find all 
// the files that match the wildcard class. 
// Note that the filename is printed on the screen.
// 
// Note: “Find First File and Report” and “Find Next File and Report” are
// recommended alternatives in order to return the responses.
//**************************************************************************
void PICASO_4DGL :: file_FindFirst(char *filename) {
    
    int size = 3 + strlen(filename);
    int i, k, j = 2;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_FIRST >> (8*1)) & 0xff;
    command[1] = (FILE_FIRST >> (8*0)) & 0xff;
    for (k = 0; k < size-1; k++) command[j++] = filename[k];
    command[j] = 0;
    
    puts("\n\rFirst file = ");
    writeCOMMAND(command, size);
    bool success = writeSectorResponse(3);
    free(command);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: %s Found = %s\n\r", filename, success ? " true" : "false");
#endif
}

//**************************************************************************
// The Find First File and Report command returns the length of the filename
// and the filename if at least 1 file exists that matches the criteria.
// 
// Wildcards are usually used so if Find First File and Report command
// returns the stringlength and filename, further tests can be made using
// “Find Next File” or “Find Next File and Report” commands to find all the files
// that match the wildcard class.
//
// you have to give the function the output char array to put filename in
//**************************************************************************
short PICASO_4DGL :: file_FindFirstRet(char *filename, char *outStr) {
    
    int size = 3 + strlen(filename);
    int i, k, j = 2;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_FIRST_RET >> (8*1)) & 0xff;
    command[1] = (FILE_FIRST_RET >> (8*0)) & 0xff;
    for (k = 0; k < size-1; k++) command[j++] = filename[k];
    command[j] = 0;
    
    writeCOMMAND(command, size);
    short len = getFilenameResponse(outStr);
    
    free(command);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Searching for %s Found filename = %s\n\r", filename, outStr);
#endif
    return len;
}

//**************************************************************************
// The Find Next File command returns true if more file exists that satisfies
// the file argument that was given for the “Find First File” or 
// “Find First File and Report” commands.
// Wildcards must be used for the “Find First File” or “Find First File and Report”
// commands else this function will always return zero as the only occurrence
// will have already been found.
// 
// Note that the filename is printed on the screen.
//**************************************************************************
void PICASO_4DGL :: file_FindNext() {
    
    char command[2];
    
    command[0] = (FILE_NEXT >> (8*1)) & 0xff;
    command[1] = (FILE_NEXT >> (8*0)) & 0xff;
    
    puts("\n\rNext file = ");
    writeCOMMAND(command, 2);
    bool success = writeSectorResponse(3);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: next file found = %s\n\r", success ? " true" : "false");
#endif
}

//**************************************************************************
// Returns length of the filename and the filename if at least 1 file exists
// that matches the criteria given for the “Find First File” or
// “Find First File and Report” commands.
// Wildcards must be used for the “Find First File” or “Find First File and Report”
// commands else this function will always return zero as the only occurrence will have
// already been found.
// 
// Wildcards are usually used, so if the “Find First File” or “Find First File and Report”
// commands return the stringlength and filename, further tests can be made using Find
// Next File and Report command to find all the files that match the wildcard class.
//**************************************************************************
short PICASO_4DGL :: file_FindNextRet(char *outStr) {
    
    char command[2];
    
    command[0] = (FILE_NEXT_RET >> (8*1)) & 0xff;
    command[1] = (FILE_NEXT_RET >> (8*0)) & 0xff;
    
    writeCOMMAND(command, 2);
    short len = getFilenameResponse(outStr);
    
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Found next filename = %s\n\r", outStr);
#endif
    return len;
}

//**************************************************************************
// Tests for the existence of the file provided with the search key. Returns TRUE if found.
//**************************************************************************
bool PICASO_4DGL :: file_Exists(char *filename) {
    
    int size = 3 + strlen(filename);
    int i, k, j = 2;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_EXISTS >> (8*1)) & 0xff;
    command[1] = (FILE_EXISTS >> (8*0)) & 0xff;
    for (k = 0; k < size-1; k++) command[j++] = filename[k];
    command[j] = 0;
    
    writeCOMMAND(command, size);
    bool success = writeSectorResponse(3);
    free(command);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: %s Found = %s\n\r", filename, success ? " true" : "false");
#endif
    return success;
}

//**************************************************************************
// Returns handle if file exists. The file ‘handle’ that is created is now used as reference for ‘filename’ 
// for further file commands such as “File Close”, etc. For File Write and File Append modes ('w' and 'a') 
// the file is created if it does not exist. If the file is opened for append and it already exists, 
// the file pointer is set to the end of the file ready for appending, else the file pointer will be 
// set to the start of the newly created file.
// 
// If the file was opened successfully, the internal error number is set to 0 (i.e. no errors) and can be 
// read with the “File Error” command. For File Read mode ('r') the file must exist else a null handle 
// (0x00, 0x00) is returned and the 'file not found' error number is set which can be read with the “File Error” command.
// 
// Note: If a file is opened for File Write mode 'w', and the file already exists, the operation will fail. 
// Unlike C and some other languages where the file will be erased ready for re-writing when opened for writing, 
// 4DGL offers a simple level of protection that ensures that a file must be purposely erased before being re-written.
// Note: Beginning with the v4.0 PmmC a file opened with FILE_APPEND may be randomly read and or written. 
// Also any altered file will have the Archive bit set in the directory entry.
//**************************************************************************
short PICASO_4DGL :: file_Open(char *filename, char openMode) {
    
    int size = 4 + strlen(filename);
    int i, k, j = 2;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_OPEN >> (8*1)) & 0xff;
    command[1] = (FILE_OPEN >> (8*0)) & 0xff;
    for (k = 0; k < size-2; k++) {
        command[j++] = filename[k];
    }
    //command[j++] = 0; // null terminated string
    
    command[size-1] = openMode; // open mode
    
    writeCOMMAND(command, size);
    short success = fileCountResponse();
    free(command);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Opened new file %s handle = %i\n\r", filename, success);
#endif
    return success;
}

//**************************************************************************
// The File Close command will close the previously opened file.
//**************************************************************************
bool PICASO_4DGL :: file_Close(short handle) {

    char command[4] = "";
    
    command[0] = (FILE_CLOSE >> (8*1)) & 0xff;
    command[1] = (FILE_CLOSE >> (8*0)) & 0xff;
    command[2] = (handle >> (8*1)) & 0xff;
    command[3] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 4);
    
    bool success = writeSectorResponse(3);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Closing file Nr. %i = %s\n\r", handle, success ? " true" : "false");
#endif
    return success;
}

//**************************************************************************
// Returns the number of bytes specified by ‘size’ from the file referenced by ‘handle’.
//**************************************************************************
short PICASO_4DGL :: file_Read(short size, short handle) {

    char command[6] = "";
    
    command[0] = (FILE_READ >> (8*1)) & 0xff;
    command[1] = (FILE_READ >> (8*0)) & 0xff;
    command[2] = (size >> (8*1)) & 0xff;
    command[3] = (size >> (8*0)) & 0xff;
    command[4] = (handle >> (8*1)) & 0xff;
    command[5] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 6);
    
    short count = readFileResponse(size);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Read %i bytes from file Nr %i\n\r", count, handle);
#endif
    return count;
}

//**************************************************************************
// The File Seek command places the file pointer at the required position in a file 
// that has been opened in 'r' (read) or 'a' (append) mode. In append mode, File Seek 
// does not expand a filesize, instead, the file pointer (handle) is set to the end 
// position of the file, e.g. assuming the file size is 10000 bytes, the File Seek 
// command with HiWord = 0x00 and LoWord = 0x1234 will set the file position to 
// 0x00001234 (byte position 4660) for the file handle, so subsequent data may be 
// read from that position onwards with “Read Character from the File”, “Read Word from the File”, 
// “Read String from the File” commands, or an image can be displayed with the “Display Image (FAT)” command.
//
// Conversely, “Write Character to the File”, “Write Word to the File”, “Write String to the File” 
// commands can write to the file at the position. A FE_EOF (end of file error) will occur if 
// you try to write or read past the end of the file, visible from the “File Error” command.
//**************************************************************************
bool PICASO_4DGL :: file_Seek(short handle, short hi, short lo) {

    char command[8] = "";
    
    command[0] = (FILE_SEEK >> (8*1)) & 0xff;
    command[1] = (FILE_SEEK >> (8*0)) & 0xff;
    command[2] = (handle >> (8*1)) & 0xff;
    command[3] = (handle >> (8*0)) & 0xff;
    command[4] = (hi >> (8*1)) & 0xff;
    command[5] = (hi >> (8*0)) & 0xff;
    command[6] = (lo >> (8*1)) & 0xff;
    command[7] = (lo >> (8*0)) & 0xff;
    writeCOMMAND(command, 8);
    
    bool success = writeSectorResponse(3);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: File pointer set = %s\n\r", success ? "true" : "false");
#endif
    return success;
}

//**************************************************************************
// Places the file pointer at the position in a file that has been opened in 
// 'r' (read) or 'a' (append) mode. In append mode, File Index does not expand 
// a filesize, instead, the file pointer (handle) is set to the end position 
// of the file, e.g. assuming the record size is 100 bytes, the File Index 
// command with HiSize = 0, LoSize = 100 and recordnum = 22 will set the file 
// position to 2200 for the file handle, so subsequent data may be read from 
// that position onwards with “Read Character from the File”, “Read Word from the File”, 
// “Read String from the File” commands or an image can be displayed with the “Display Image (FAT)” command.
// 
// Conversely, the “Write Character to the File”, “Write Word to the File”, 
// “Write String to the File” commands can write to the file at the position. 
// A FE_EOF (end of file error) will occur if you try to write or read past 
// the end of the file, visible from the “File Error” command.
//**************************************************************************
bool PICASO_4DGL :: file_Index(short handle, short hi, short lo, short rec) {

    char command[10] = "";
    
    command[0] = (FILE_INDEX >> (8*1)) & 0xff;
    command[1] = (FILE_INDEX >> (8*0)) & 0xff;
    command[2] = (handle >> (8*1)) & 0xff;
    command[3] = (handle >> (8*0)) & 0xff;
    command[4] = (hi >> (8*1)) & 0xff;
    command[5] = (hi >> (8*0)) & 0xff;
    command[6] = (lo >> (8*1)) & 0xff;
    command[7] = (lo >> (8*0)) & 0xff;
    command[8] = (rec >> (8*1)) & 0xff;
    command[9] = (rec >> (8*0)) & 0xff;
    writeCOMMAND(command, 10);
    
    bool success = writeSectorResponse(3);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: File pointer set = %s\n\r", success ? "true" : "false");
#endif
    return success;
}

//**************************************************************************
// The File Tell command returns the current value of the file pointer.
//**************************************************************************
int PICASO_4DGL :: file_Tell(short handle) {

    char command[4] = "";
    
    command[0] = (FILE_TELL >> (8*1)) & 0xff;
    command[1] = (FILE_TELL >> (8*0)) & 0xff;
    command[2] = (handle >> (8*1)) & 0xff;
    command[3] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 4);
    
    int point = fileTellResponse();
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Pointer value = %i\n\r", point);
#endif
    return point;
}


//**************************************************************************
// The File Write command returns the current value of the file pointer.
// size - Number of bytes to be written. Maximum that can be written at one time is 512 bytes.
// source - String of Data without Null terminator.
//**************************************************************************
short PICASO_4DGL :: file_Write(short num, char *str, short handle) {

    int size = 6 + strlen(str);
    int i, k, j = 4;
    char *command;
    command = (char *)malloc(sizeof(char) * size);
    for(i = 0; i < size; i++) command[i] = 0;
    
    command[0] = (FILE_WRITE >> (8*1)) & 0xff;
    command[1] = (FILE_WRITE >> (8*0)) & 0xff;
    command[2] = (num >> (8*1)) & 0xff;
    command[3] = (num >> (8*0)) & 0xff;
    
    for (k = 0; k < strlen(str); k++) {
        command[j++] = str[k];
    }
    command[j++] = (handle >> (8*1)) & 0xff;
    command[j] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, size);
    
    short count = fileCountResponse();
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Pointer value = %i\n\r", count);
#endif
    return count;
}

//**************************************************************************
// The File Size command reads the 32 bit file size.
//**************************************************************************
int PICASO_4DGL :: file_Size(short handle) {

    char command[4] = "";
    
    command[0] = (FILE_SIZE >> (8*1)) & 0xff;
    command[1] = (FILE_SIZE >> (8*0)) & 0xff;
    command[2] = (handle >> (8*1)) & 0xff;
    command[3] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 4);
    
    int size = fileTellResponse();
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: File %i size = %i\n\r", handle, size);
#endif
    return size;
}

//**************************************************************************
// Display an image from the file stream at screen location specified by x, y 
// (top left corner). If there is more than 1 image in the file, it can be 
// accessed with the “File Seek” command
//**************************************************************************
bool PICASO_4DGL :: file_Image(short x, short y, short handle) {

    char command[8] = "";
    
    command[0] = (FILE_IMAGE >> (8*1)) & 0xff;
    command[1] = (FILE_IMAGE >> (8*0)) & 0xff;
    command[2] = (x >> (8*1)) & 0xff;
    command[3] = (x >> (8*0)) & 0xff;
    command[4] = (y >> (8*1)) & 0xff;
    command[5] = (y >> (8*0)) & 0xff;
    command[6] = (handle >> (8*1)) & 0xff;
    command[7] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 8);
    
    bool success = !writeSectorResponse(3);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Display image = %s\n\r", success ? "true" : "false");
#endif
    return success;
}

//**************************************************************************
// The Screen Capture command saves an image of the screen shot to file at the current file position.
// The image can later be displayed with the “Display Image (FAT)” command.
// The file may be opened in append mode to accumulate multiple images.
// ater, the images can be displayed with the “File Seek” command.
// The image is saved from x, y (with respect to top left corner), and the capture 
// area is determined by "width" and "height".
//**************************************************************************
bool PICASO_4DGL :: file_ScreenCapture(short x, short y, short width, short height, short handle) {

    char command[12] = "";
    
    command[0] = (FILE_S_CAPTURE >> (8*1)) & 0xff;
    command[1] = (FILE_S_CAPTURE >> (8*0)) & 0xff;
    command[2] = (x >> (8*1)) & 0xff;
    command[3] = (x >> (8*0)) & 0xff;
    command[4] = (y >> (8*1)) & 0xff;
    command[5] = (y >> (8*0)) & 0xff;
    command[6] = (width >> (8*1)) & 0xff;
    command[7] = (width >> (8*0)) & 0xff;
    command[8] = (height >> (8*1)) & 0xff;
    command[9] = (height >> (8*0)) & 0xff;
    command[10] = (handle >> (8*1)) & 0xff;
    command[11] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 12);
    
    bool success = !writeSectorResponse(3);
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Screen capture = %s\n\r", success ? "true" : "false");
#endif
    return success;
}

//**************************************************************************
// This function reads a word (2 bytes) from the file, at the position indicated 
// by the associated file-position pointer (set by the “File Seek” or “File Index” commands) 
// and advances the pointer appropriately (incremented by 2). The file must be 
// previously opened with 'r' (read) mode.
//**************************************************************************
short PICASO_4DGL :: file_GetW(short handle) {

    char command[4] = "";
    
    command[0] = (FILE_GET_W >> (8*1)) & 0xff;
    command[1] = (FILE_GET_W >> (8*0)) & 0xff;
    command[2] = (handle >> (8*1)) & 0xff;
    command[3] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 4);
    
    short word = fileErrorResponse(); // get 2 bytes from file
#ifdef DEBUGMODE
    pc.printf("\n\r DEBUG: Read word = %i\n\r", word);
#endif
    return word;
}

//**************************************************************************
// This function reads a line of text from a file at the current file position 
// indicated by the associated file-position pointer (set by the “File Seek” 
// or “File Index” commands) and advances the pointer appropriately. 
// Characters are read until either a newline or an EOF is received or until 
// the specified maximum "size" is reached. In all cases, the string is null 
// terminated. The file must be previously opened with 'r' (read) mode.
//**************************************************************************
short PICASO_4DGL :: file_GetS(short size, short handle, char *str) {

    char command[6] = "";
    
    command[0] = (FILE_GET_S >> (8*1)) & 0xff;
    command[1] = (FILE_GET_S >> (8*0)) & 0xff;
    command[2] = (size >> (8*1)) & 0xff;
    command[3] = (size >> (8*0)) & 0xff;
    command[4] = (handle >> (8*1)) & 0xff;
    command[5] = (handle >> (8*0)) & 0xff;
    writeCOMMAND(command, 6);
    
    short count = getFilenameResponse(str); // get specified count of bytes from file
#ifdef DEBUGMODE
    //pc.printf("\n\r DEBUG: Read %i bytes from %i\n\r", count, handle);
#endif
    return count;
}