Add file listing of SD card through to TS
This commit is contained in:
parent
4e15c77c00
commit
07bfc6025c
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue