Add file listing of SD card through to TS

This commit is contained in:
Josh Stewart 2021-11-24 10:23:15 +11:00
parent 4e15c77c00
commit 07bfc6025c
5 changed files with 145 additions and 34 deletions

View File

@ -23,6 +23,7 @@
#define SD_STATUS_CARD_ERROR 4 //0=no error, 1=error
#define SD_STATUS_CARD_VERSION 5 //0=1.x, 1=2.x
#define SD_STATUS_CARD_FS 6 //0=no FAT16, 1=FAT32
#define SD_STATUS_CARD_UNUSED 7 //0=normal, 1=unused
#define SD_SECTOR_SIZE 512 // Standard SD sector size
@ -35,7 +36,9 @@
//Test values only
#define SD_LOG_FILE_SIZE 10000000 //Defuault 10mb file size
#define LOG_FILENAME "SdioLogger.csv"
#define MAX_LOG_FILES 10000
#define LOG_FILE_PREFIX "SPD_"
#define LOG_FILE_EXTENSION "csv"
#define RING_BUF_CAPACITY SD_LOG_ENTRY_SIZE * 10 //Allow for 10 entries in the ringbuffer. Will need tuning
/*
@ -50,6 +53,7 @@ extern ExFile logFile;
extern RingBuf<ExFile, RING_BUF_CAPACITY> rb;
extern uint8_t SD_status;
extern uint16_t currentLogFileNumber;
void initSD();
void writeSDLogEntry();
@ -60,6 +64,8 @@ void setTS_SD_status();
void formatExFat();
bool createLogFile();
void dateTime(uint16_t*, uint16_t*, uint8_t*); //Used for timestamping with RTC
uint16_t getNextSDLogFileNumber();
bool getSDLogFileDetails(uint8_t* , uint16_t);

View File

@ -9,6 +9,7 @@ SdExFat sd;
ExFile logFile;
RingBuf<ExFile, RING_BUF_CAPACITY> rb;
uint8_t SD_status = SD_STATUS_OFF;
uint16_t currentLogFileNumber;
void initSD()
{
@ -32,9 +33,11 @@ void initSD()
bool createLogFile()
{
char filenameBuffer[24];
//TunerStudio only supports 8.3 filename format.
char filenameBuffer[13]; //8 + 1 + 3 + 1
bool returnValue = false;
/*
//Filename format is: YYYY-MM-DD_HH.MM.SS.csv
char intBuffer[5];
itoa(rtc_getYear(), intBuffer, 10);
@ -55,6 +58,14 @@ bool createLogFile()
itoa(rtc_getSecond(), intBuffer, 10);
strcat(filenameBuffer, intBuffer);
strcat(filenameBuffer, ".csv");
*/
if(currentLogFileNumber == 0)
{
//Lookup the next available file number
currentLogFileNumber = getNextSDLogFileNumber();
}
//Create the filename
sprintf(filenameBuffer, "%s%04d.%s", LOG_FILE_PREFIX, currentLogFileNumber, LOG_FILE_EXTENSION);
//if (!logFile.open(LOG_FILENAME, O_RDWR | O_CREAT | O_TRUNC))
if (logFile.open(filenameBuffer, O_RDWR | O_CREAT | O_TRUNC))
@ -65,6 +76,87 @@ bool createLogFile()
return returnValue;
}
uint16_t getNextSDLogFileNumber()
{
uint16_t nextFileNumber = 1;
char filenameBuffer[13]; //8 + 1 + 3 + 1
sprintf(filenameBuffer, "%s%04d.%s", LOG_FILE_PREFIX, nextFileNumber, LOG_FILE_EXTENSION);
//Lookup the next available file number
while( (nextFileNumber < MAX_LOG_FILES) && (sd.exists(filenameBuffer)) )
{
nextFileNumber++;
sprintf(filenameBuffer, "%s%04d.%s", LOG_FILE_PREFIX, nextFileNumber, LOG_FILE_EXTENSION);
}
return nextFileNumber;
}
bool getSDLogFileDetails(uint8_t* buffer, uint16_t logNumber)
{
bool fileFound = false;
if(logFile.isOpen()) { endSDLogging(); }
char filenameBuffer[13]; //8 + 1 + 3 + 1
sprintf(filenameBuffer, "%s%04d.%s", LOG_FILE_PREFIX, logNumber, LOG_FILE_EXTENSION);
if(sd.exists(filenameBuffer))
{
fileFound = true;
logFile = sd.open(filenameBuffer, O_RDONLY);
//Copy the filename into the buffer. Note we do not copy the termination character or the fullstop
for(byte i=0; i<12; i++)
{
//We don't copy the fullstop to the buffer
//As TS requires 8.3 filenames, it's always in the same spot
if(i < 8) { buffer[i] = filenameBuffer[i]; } //Everything before the fullstop
else if(i > 8) { buffer[i-1] = filenameBuffer[i]; } //Everything after the fullstop
}
//Is File or ignore
buffer[11] = 1;
//No idea
buffer[12] = 0;
//5 bytes for FAT creation date/time
uint16_t pDate = 0;
uint16_t pTime = 0;
logFile.getCreateDateTime(&pDate, &pTime);
buffer[13] = 0; //Not sure what this byte is for yet
buffer[14] = lowByte(pDate);
buffer[15] = highByte(pDate);
buffer[16] = lowByte(pDate);
buffer[17] = highByte(pDate);
//Sector number (4 bytes) - This byte order might be backwards
uint32_t sector = logFile.firstSector();
buffer[18] = ((sector) & 255);
buffer[19] = ((sector >> 8) & 255);
buffer[20] = ((sector >> 16) & 255);
buffer[21] = ((sector >> 24) & 255);
//Unsure on the below 6 bytes, possibly last accessed or modified date/time?
buffer[22] = 0;
buffer[23] = 0;
buffer[24] = 0;
buffer[25] = 0;
buffer[26] = 0;
buffer[27] = 0;
//File size (4 bytes). Little endian
uint32_t size = logFile.fileSize();
buffer[28] = ((size) & 255);
buffer[29] = ((size >> 8) & 255);
buffer[30] = ((size >> 16) & 255);
buffer[31] = ((size >> 24) & 255);
}
return fileFound;
}
void beginSDLogging()
{
if(SD_status == SD_STATUS_READY)
@ -183,6 +275,7 @@ void setTS_SD_status()
else { BIT_CLEAR(currentStatus.TS_SD_Status, SD_STATUS_CARD_ERROR); }// CARD has no error
BIT_SET(currentStatus.TS_SD_Status, SD_STATUS_CARD_FS); // CARD has a FAT32 filesystem (Though this will be exFAT)
BIT_CLEAR(currentStatus.TS_SD_Status, SD_STATUS_CARD_UNUSED); //Unused bit is always 0
}

View File

@ -10,30 +10,6 @@
#ifndef COMMS_H
#define COMMS_H
//Hardcoded TunerStudio addresses/commands for various SD/RTC commands
#define SD_READWRITE_PAGE 0x11
#define SD_RTC_PAGE 0x07
#define SD_READ_STAT_OFFSET 0x0000
#define SD_READ_STAT_LENGTH 0x1000
#define SD_READ_DIR_OFFSET 0x0100
#define SD_READ_DIR_LENGTH 0x0200
#define SD_READ_SEC_OFFSET 0x0200
#define SD_READ_SEC_LENGTH 0x0400
#define SD_READ_STRM_OFFSET 0x0400
#define SD_READ_STRM_LENGTH 0x0100
#define SD_WRITE_DO_OFFSET 0x0000
#define SD_WRITE_DO_LENGTH 0x0001
#define SD_WRITE_SEC_OFFSET 0x0300
#define SD_WRITE_SEC_LENGTH 0x0402
#define SD_ERASEFILE_OFFSET 0x0600
#define SD_ERASEFILE_LENGTH 0x0600
#define SD_SPD_TEST_OFFSET 0x0700
#define SD_SPD_TEST_LENGTH 0x0400
#define SD_RTC_WRITE_OFFSET 0x7E02
#define SD_RTC_WRITE_LENGTH 0x0900
#define SD_RTC_READ_OFFSET 0x4D02
#define SD_RTC_READ_LENGTH 0x0800
extern byte currentPage;//Not the same as the speeduino config page numbers
extern bool isMap; /**< Whether or not the currentPage contains only a 3D map that would require translation */

View File

@ -31,6 +31,7 @@ uint16_t serialPayloadLength = 0;
bool serialReceivePending = false; /**< Whether or not a serial request has only been partially received. This occurs when a the length has been received in the serial buffer, but not all of the payload or CRC has yet been received. */
uint16_t serialBytesReceived = 0;
uint32_t serialCRC = 0;
uint16_t SDcurrentDirChunk;
uint8_t serialPayload[SERIAL_BUFFER_SIZE]; /**< Pointer to the serial payload buffer. */
/** Processes the incoming data on the serial buffer based on the command sent.
@ -397,9 +398,8 @@ void processSerialCommand()
serialPayload[0] = SERIAL_RC_OK;
//Serial.write(currentStatus.TS_SD_Status);
serialPayload[1] = 5;
serialPayload[1] = currentStatus.TS_SD_Status;
//serialPayload[1] = 5;
serialPayload[2] = 0;
//All other values are 2 bytes
@ -430,10 +430,33 @@ void processSerialCommand()
sendSerialPayload(&serialPayload, 17);
}
//else if(length == 0x202)
else if((offset == SD_READ_DIR_OFFSET) && (length == SD_READ_DIR_LENGTH))
{
//Send file details
serialPayload[0] = SERIAL_RC_OK;
uint16_t logFileNumber = (SDcurrentDirChunk * 16) + 1;
uint8_t filesInCurrentChunk = 0;
uint16_t payloadIndex = 1;
while((filesInCurrentChunk < 16) && (getSDLogFileDetails(&serialPayload[payloadIndex], logFileNumber) == true))
{
logFileNumber++;
filesInCurrentChunk++;
payloadIndex += 32;
}
serialPayload[33] = lowByte(SDcurrentDirChunk);
serialPayload[34] = highByte(SDcurrentDirChunk);
sendSerialPayload(&serialPayload, (payloadIndex + 2));
}
else if((offset == SD_READ_STAT_OFFSET) && (length == SD_READ_STAT_LENGTH))
{
//File info
}
}
else if(cmd == 0x14)
{
@ -572,7 +595,16 @@ void processSerialCommand()
4 Load status variable
5 Init SD card
*/
setTS_SD_status(); //Set SD status values
uint8_t command = serialPayload[7];
if(command == 4) { setTS_SD_status(); } //Set SD status values
sendSerialReturnCode(SERIAL_RC_OK);
}
else if((valueOffset == SD_WRITE_DIR_OFFSET) && (chunkSize == SD_WRITE_DIR_LENGTH))
{
//Begin SD directory read. Value in payload represents the directory chunk to read
//Directory chunks are each 32 files long
SDcurrentDirChunk = word(serialPayload[7], serialPayload[8]);
sendSerialReturnCode(SERIAL_RC_OK);
}
else if((valueOffset == SD_WRITE_SEC_OFFSET) && (chunkSize == SD_WRITE_SEC_LENGTH))

View File

@ -15,14 +15,17 @@
#define SD_RTC_PAGE 0x07
#define SD_READ_STAT_OFFSET 0x0000
#define SD_READ_STAT_LENGTH 0x1000
#define SD_READ_DIR_OFFSET 0x0100
#define SD_READ_DIR_LENGTH 0x0200
#define SD_READ_DIR_OFFSET 0x0000
#define SD_READ_DIR_LENGTH 0x0202
#define SD_READ_SEC_OFFSET 0x0200
#define SD_READ_SEC_LENGTH 0x0400
#define SD_READ_STRM_OFFSET 0x0400
#define SD_READ_STRM_LENGTH 0x0100
#define SD_WRITE_DO_OFFSET 0x0000
#define SD_WRITE_DO_LENGTH 0x0001
//#define SD_WRITE_DO_LENGTH 0x0001
#define SD_WRITE_DO_LENGTH 0x0100
#define SD_WRITE_DIR_OFFSET 0x0100
#define SD_WRITE_DIR_LENGTH 0x0200
#define SD_WRITE_SEC_OFFSET 0x0300
#define SD_WRITE_SEC_LENGTH 0x0402
#define SD_ERASEFILE_OFFSET 0x0600
@ -54,6 +57,7 @@ extern bool serialReceivePending; /**< Whether or not a serial request has only
extern uint8_t serialPayload[SERIAL_BUFFER_SIZE]; /**< Pointer to the serial payload buffer. */
extern uint16_t serialBytesReceived; /**< The number of bytes received in the serial buffer during the current command. */
extern bool serialWriteInProgress;
extern uint16_t SDcurrentDirChunk;
void parseSerial();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable.
void processSerialCommand();