package uk.org.smithfamily.mslogger.comms;
import uk.org.smithfamily.mslogger.ApplicationSettings;
import uk.org.smithfamily.mslogger.ecuDef.InjectedCommand;
import uk.org.smithfamily.mslogger.ecuDef.Megasquirt;
/**
* Class to send command to the SD card
*/
public class MS3SDCard
{
private Megasquirt ecu;
public MS3SDCard()
{
this.ecu = ApplicationSettings.INSTANCE.getEcuDefinition();
}
/**
* SD reset and go (w 00 00)
*
* Send w <canid> 11 00 00 00 01 00
*/
public void resetAndGo()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 00, 00, 01, 00 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_RESET_AND_GO);
ecu.injectCommand(writeToRAM);
}
/**
* SD reset and wait (w 00 00)
*
* Send w <canid> 11 00 00 00 01 01
*
*/
public void resetAndWait()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 00, 00, 01, 01 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_RESET_AND_WAIT);
ecu.injectCommand(writeToRAM);
}
/**
* SD stop logging (w 00 00)
*
* Send w <canid> 11 00 00 00 01 02
*/
public void stopLogging()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 00, 00, 01, 02 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_STOP_LOGGING);
ecu.injectCommand(writeToRAM);
}
/**
* SD start logging (w 00 00)
*
* Send w <canid> 11 00 00 00 01 03
*/
public void startLogging()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 00, 00, 01, 03 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_START_LOGGING);
ecu.injectCommand(writeToRAM);
}
/**
* SD reinitialise card (w 00 00)
*
* Send w <canid> 11 00 00 00 01 05
*/
public void reinitialiseCard()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 00, 00, 01, 05 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_REINITIALISE_CARD);
ecu.injectCommand(writeToRAM);
}
/**
* SD status command
*
* Send: w <canid> 11 00 00 00 01 04
* Send: r <canid> 11 00 00 00 10
*
* Returns: 16 bytes of info
* Byte 0 = Card status (same as outpc.sd_status)
* bit 0: 0=No card, 1=Card present
* bit 1: 0=SD, 1=SDHC
* bit 2: 0=Not Ready, 1=Ready
* bit 3: 0=Not logging, 1=Logging
* bit 4: 0=No error, 1=Error
* bit 5: 0=V1.x, 1=V2.0 card
* bit 6: 0=FAT16, 1=FAT32
* bit 7: 0=normal, 1=WTF enabled (this may change)
* Byte 1 = Error code
* Bytes 2-3 = Sector size
* Bytes 4-7 = Card size in sectors
* Bytes 8-9 = No. files in directory
* Bytes 10-13 = Sector number of directory
* Bytes 14-15 = undefined
*
* Note! Only use the status command when the card is already idle. Read outpc.sd_status first.
*/
public void status()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 00, 00, 01, 04 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_STATUS_WRITE);
ecu.injectCommand(writeToRAM);
byte[] commandRead = { (byte) 'r', 00, 11, 00, 00, 00, 10 };
writeToRAM = new InjectedCommand(commandRead, 300, true, Megasquirt.MS3_SD_CARD_STATUS_READ);
ecu.injectCommand(writeToRAM);
}
/**
* SD read directory command
*
* Send: w <canid> 11 00 01 00 02 <U16 directory chunk>
* Send: r <canid> 11 00 00 02 02
*
* Returns: a sector with 32 bytes per file in root directory, plus U16 chunk number
* Bytes 0-10 = 8.3 filename, space padded as per FAT directory
* Byte 11 = 0=ignore, 1=file
* Bytes 12-15 = undefined
* Bytes 16-23 = absolute sector number (big endian)
* Bytes 24-31 = file size _in_bytes_ (little endian direct from media)
*
* Where the directory is longer than 32 entries, multiple reads will be required, chunk 0, 1, etc.
*
* Note 1. The format is similar to the FAT16 directory structure, but MS3 returns sector number
* instead of cluster number. Non MS3 log files are ignored and not reported.
*
* Note 2. All MS3 log files are created by MS3 as contiguous files. If these files are disturbed from
* the PC end and made non contiguous, data corruption on the SDcard will occur as the firmware
* does not support fragmentation due to the severe speed penalty it would incurr.
*
* Note 3. directory chunk no. starts at 0.
*
*/
public void readDirectory(byte chunk)
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 01, 00, 02, chunk };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_READ_DIRECTORY_WRITE);
ecu.injectCommand(writeToRAM);
}
/**
* SD read sector command
*
* Send: w <canid> 11 00 02 00 04 <U32 sector number>
* Send: r <canid> 11 00 00 02 04
*
* <sector data....> <U32 sector number>
*
* Returns: Sector size bytes of data + sector number.
*
* Sector size is always 512 bytes, can check with command 00 00
*/
public void readSector()
{
}
/**
* SD write sector command
*
* Send: w <canid> 11 00 03 02 04 <sector data......> <U32 sector number>
*
* The data sent is a full sector and then the 4 bytes of sector number. Note 02 above is for 512 byte sector.
*
* Used incorrectly this command could corrupt the data on SDcard as it permits re-writing any area of the device (including MBR, FAT, directories etc.)
*/
public void writeSector()
{
}
/**
* SD read stream command
*
* Send: w <canid> 11 00 04 00 01 01
*
* Then 8bit data from the selected stream ADC input is continuously sent by serial. Power cycle the MS3 to stop.
*
* Note! Returned data is raw and not newserial packetised.
*/
public void readStream()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 04, 00, 01, 01 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_READ_STREAM);
ecu.injectCommand(writeToRAM);
}
/**
* SD read compressed file command
*
* Send: w <canid> 11 00 05 00 08 <U32 sector number> <U32 sector count>
* Send: r <canid> 14 <U16 block num> 08 00
*
* Returns packet with payload: <U08 ok> <U16 block no.> <....data bytes....>
*
* This will be 2048 bytes of data until the last block of data, so normally 2057 bytes total packet size.
* Block number increments each time starting from zero. (A future release will allow the same block
* to be requested again in case of a transmission error.)
*/
public void readCompressedFile()
{
}
/**
* SD erase file command
*
* Send: w <canid> 11 00 06 00 06 <ascii 4 byte file number> <U16 start dirblock>
*
* For filename LOG0002.MS3 send ascii '0' '0' '0' '2'. (48, 48, 48, 50)
*
* Sending the actual directory block no. that the file entry appears in will speed up the deletion.
*
* Otherwise use zero to force code to find it. MS3 will delete the directory entry and the FAT chain.
*
* Returns nothing.
*
* Busy bit will be set during operation. Poll for completion.
*/
public void eraseFile()
{
}
/**
* SD speed test command
*
* Send: w <canid> 11 00 07 00 04 <U32 sector number> <U32 num sectors>
*
* The code will blindy erase the sectors you request.
* Poll outpc.sd_status until card is not busy.
*
* Send: r <canid> 11 00 00 00 0d
*
* Returns:
* U32 sector down count (use for progress meter)
* U32 total time 0.1ms units
* U16 minimum time
* U16 maximum time
* U08 stat 0 = running 1 = done 2 = error
*/
public void speedTest()
{
}
/**
* RTC read command
*
* Send: w <canid> 11 00 08 00 08
* Send: r <canid> 11 00 00 02 02
*
* Returns 8 bytes: <U08 sec> <U08 min> <U08 hr> <U08 date> <U08 mon> <U16 year>
*
* Reads the local or CAN realtime clock
*/
public void RTCRead()
{
byte[] commandWrite = { (byte) 'w', 00, 11, 00, 8, 00, 8 };
InjectedCommand writeToRAM = new InjectedCommand(commandWrite, 300, true, Megasquirt.MS3_SD_CARD_READ_RTC_WRITE);
ecu.injectCommand(writeToRAM);
byte[] commandRead = { (byte) 'r', 00, 11, 00, 00, 02, 02 };
writeToRAM = new InjectedCommand(commandRead, 300, true, Megasquirt.MS3_SD_CARD_READ_RTC_READ);
ecu.injectCommand(writeToRAM);
}
/**
* RTC write command
*
* Send: w <canid> 11 00 09 00 08 <U08 sec> <U08 min> <U08 hr> <U08 date> <U08 mon> <U16 year>
*
* Sets the (local) realtime clock
*/
public void RTCWrite()
{
}
}