Page 1 of 3
SDFileSystem Version 4.0.9
Posted: Fri Mar 21, 2008 8:41 am
by Steven
Dear All,
Following the recent release of Version 3.1.1 of the SDFileSystem module that added support for SDHC cards and FAT32, I am pleased to announce the release of Version 4.0.9 on the wiki
http://www.sfcompiler.co.uk/wiki/pmwiki ... temVersion).
The main addition to this version is support for multiple files, but new commands have also been added:
CloseAll
SaveAll
FreeFile
NewRecord, SetRecord, GetRecord and NumberOfRecords
Truncate
CopyFile
MoveFileCut, MoveFilePaste
There are also several important bug fixes.
I would be grateful if you were to post a reply to this topic if you try the new version so that I can judge the uptake of it.
Kind regards,
Steve
New Version working well for me
Posted: Tue Apr 01, 2008 8:35 pm
by Tom Estes
Steven
I'm using the new version on an 18F4620 and all is good. I'm using it in a single file logging application so am not giving it too much of a workout.
Thanks for your excellent contributions, much appreciated!
Tom
Posted: Tue Apr 01, 2008 8:45 pm
by Steven
That's great to hear - thanks for the info.
Steve
Posted: Tue Apr 01, 2008 10:13 pm
by rmteo
What is a rough estimate of the amount of ROM and RAM required for this latest version of the SD Filesystem?
Posted: Tue Apr 01, 2008 10:30 pm
by Steven
As a guide, the following code takes 18891 bytes of ROM and needs 978 bytes of RAM:
Code: Select all
{
*****************************************************************************
* Name : UNTITLED.BAS *
* Author : S Wright *
* Notice : Copyright (c) 2007 S Wright *
* : All Rights Reserved *
* Date : 25/10/2007 *
* Version : 1.0 *
* Notes : *
* : *
*****************************************************************************
}
Device = 18F4620
Clock = 40
Config OSC = HSPLL
// Uses USART, SDFileSystem, Convert and String libraries...
#option SD_SPI = MSSP
#option SD_SPI_SPEED = spiOscDiv4
#option SD_SUPPORT_SUB_DIRECTORIES = True
#option SD_SUPPORT_MULTIPLE_FILES = True
Include "USART.bas"
Include "SDFileSystem.bas"
Include "String.bas"
Include "Convert.bas"
Const ClockDiv = _clock * 1000000
Dim Timer As TMR1L.AsWord // Alias to Timer1
Dim TimerOn As T1CON.Booleans(0) // Start and stop
Dim TimerInterruptsEnabled As PIE1.Booleans(0) // Enable interrupts
Dim Counter As LongWord
Dim CounterUpper As Counter.Word1
Dim Index1 As Byte
Dim Index2 As Word
Dim ReadOK As Boolean
Dim SerialNum As LongWord
Dim Response As Byte
Dim InitOK As Boolean
// Timer interrupt handler - every time Timer1 overflows, we
// need to increment the upper word of our big 32 bit counter...
Interrupt OnTimer()
Inc(CounterUpper)
PIR1.0 = 0
End Interrupt
Sub TimerStart()
Timer = 0 // Clear timer one
CounterUpper = 0 // Clear upper count value
TimerOn = True // Start timer
End Sub
Sub TimerStop()
TimerOn = False // Timer off
Counter.Word0 = Timer // Save what's left in timer one
End Sub
// Display time
Sub DisplayTime()
Dim Time As Float
Time = 4 * Counter / ClockDiv
USART.Write("Time Taken: ", FloatToStr(Time, 4, 2), " sec", 13, 10)
End Sub
// Main program...
SetBaudrate(br19200)
USART.ReadTerminator = #13
DelayMS(100)
TimerInterruptsEnabled = True // Enable timer interrupts
Enable(OnTimer) // Assign the interrupt handler
Repeat
InitOK = False
USART.Write("Insert SD/MMC:", 13, 10)
Repeat
Response = SD.Init
Until Response <> errNoResponse
If Response = errOK Then
USART.Write("Init Successful - Card Pre-formatted", 13, 10)
USART.Write("Quick Formatting:", 13, 10)
InitOK = SD.QuickFormat
If InitOK Then
USART.Write("QuickFormat Successful", 13, 10)
Else
USART.Write("QuickFormat Not Successful", 13, 10)
EndIf
ElseIf Response = errInvalidFormat Then
USART.Write("Init Failed - Card Not Formatted", 13, 10)
USART.Write("Formatting Now:", 13, 10)
If SD.Format(1) = errOK Then
USART.Write("Format Successful", 13, 10)
InitOK = True
Else
USART.Write("Format Not Successful", 13, 10)
EndIf
EndIf
If InitOK Then
SerialNum = SD.SerialNumber
USART.Write("Serial Number: ", HexToStr(SerialNum, 8))
Select SerialNum
Case $00260010 USART.Write(" (IT Works 64MB MMC)", 13, 10)
Case $010366FE USART.Write(" (IT Works 64MB SD)", 13, 10)
Case $407CA4F6 USART.Write(" (ByteStor 128MB SD)", 13, 10)
Case $5048B63C USART.Write(" (Integral 128MB SD)", 13, 10)
Case $81B7762D USART.Write(" (Toshiba 512MB SD)", 13, 10)
Case $239005B8 USART.Write(" (Kingston 1GB SD)", 13, 10)
Case $0008C724 USART.Write(" (Sandisk UltraII 4GB SD)", 13, 10)
Else USART.Write(13, 10)
EndSelect
USART.Write("FAT Type: ")
Select SD.FATType
Case sdFAT16 USART.Write("FAT16", 13, 10)
Case sdFAT32 USART.Write("FAT32", 13, 10)
EndSelect
SD.MkDir("FOLDER")
SD.ChDir("FOLDER")
USART.Write("Opening New File:", 13, 10)
SD.NewFile(0, "TEST0001.TXT")
USART.Write("1MB Write Started:", 13, 10)
TimerStart()
Index2 = 0
Repeat
Index1 = 0
Repeat
SD.Write(0, Index1)
Inc(Index1)
Until Index1 = $00
Inc(Index2)
Until Index2 = $1000
TimerStop()
SD.CloseFile(0)
USART.Write("1MB Write Completed", 13, 10)
DisplayTime()
If Not SD.RWError Then
USART.Write("Write OK - No RWErrors", 13, 10)
Else
USART.Write("WARNING - Write RWErrors Encountered!", 13, 10)
EndIf
USART.Write("Opening File:", 13, 10)
SD.OpenFile(0, "TEST0001.TXT")
USART.Write("1MB Read Started:", 13, 10)
ReadOK = True
TimerStart()
Index2 = 0
Repeat
Index1 = 0
Repeat
If SD.ReadByte(0) <> Index1 Then
ReadOK = False
EndIf
Inc(Index1)
Until Index1 = $00
Inc(Index2)
Until Index2 = $1000
TimerStop()
SD.CloseFile(0)
USART.Write("1MB Read Completed", 13, 10)
DisplayTime()
If ReadOK Then
USART.Write("Read OK - Readback Identical", 13, 10)
Else
USART.Write("WARNING - Read Errors Encountered - Readback Not Identical!", 13, 10)
EndIf
If Not SD.RWError Then
USART.Write("Read OK - No RWErrors", 13, 10)
Else
USART.Write("WARNING - Read RWErrors Encountered!", 13, 10)
EndIf
EndIf
USART.Write("------------------------------------------------------------", 13, 10)
Repeat
Until Not SD.DiskMounted
Until False
It's a fairly hungry module and the code has had to grow somewhat to enable FAT32 more than anything else. The multiple file support, if enabled, also adds a little more. Bear in mind also that a fair amount of the code goes into error checking and reporting, to try and prevent possible data loss from cards as much as possible, in the event of user code errors or unexpected events, such as trying to write to a file that failed to open. I'm not guaranteeing that its 100% bullet proof now, but it is fairly rigorous in its error checking.
Note though that the ROM and RAM figures are very approximate, as it does depend very much on which commands in the SD library are used. If you have a code sample that you would like me to compile with the new version, then post it and I'll be happy to report the exact usage for you.
Regards,
Steve
Posted: Tue Apr 01, 2008 10:42 pm
by rmteo
Thank you very much for your detailed reply.
Posted: Thu Apr 03, 2008 7:17 am
by tass
hi steven,
i want to suggest you a litle (insignifiant) change in your SdFile System library the initial code is:
Code: Select all
{
********************************************************************************
* Name : ReadNBytes (PUBLIC) *
* Purpose : Read N bytes from file. *
* : Check EOF for EOF condition *
********************************************************************************
}
#if SD_SUPPORT_MULTIPLE_FILES = TRUE
Public Sub ReadNBytes(pFileNumber As ShortInt, ByRef pReturnArray() As Byte, pNumberOfBytes As Word)
Dim Address As Word
Dim FileByte As Byte
FileNumber(pFileNumber)
#else
Public Sub ReadNBytes(ByRef pReturnArray() As Byte, pNumberOfBytes As Word)
Dim Address As Word
Dim FileByte As Byte
#endif
Address = AddressOf(pReturnArray(0))
While pNumberOfBytes > 0
FileByte = ReadByteSub()
FSR0 = Address
POSTINC0 = FileByte
Dec(pNumberOfBytes)
Inc(Address)
Wend
End Sub
and the suggestion is:
Code: Select all
#if SD_SUPPORT_MULTIPLE_FILES = TRUE
Public Sub ReadNBytes(pFileNumber As ShortInt, Address As LongWord, pNumberOfBytes As Word)
FileNumber(pFileNumber)
#else
Public Sub ReadNBytes( Address As LongWord, pNumberOfBytes As Word)
#endif
FSR0 = Address
While pNumberOfBytes > 0
POSTINC0 = ReadByteSub()
Dec(pNumberOfBytes)
Inc(Address)
Wend
End Sub
the call of the sub will be like this:
Code: Select all
ReadNBytes(@ReturnArray, NumberOfBytes)
Posted: Thu Apr 03, 2008 7:39 am
by Steven
Tass, thanks for the suggestion. I can see the value of this and might add it as an overloaded version of the ReadNBytes sub. You have to be careful with FSR0 however, as the module uses this elsewhere, including when reading from each sector. It needs resetting on each POSTINC0 as the ReadByteSub command may have altered it. Hence the convoluted way of reading a byte, then setting FSR0, followind by the POSTINC0 instruction.
Thanks for the suggestion,
Steve
Posted: Thu Apr 03, 2008 7:51 am
by tass
it will be a good idea if you can add it as an overload sub because in the programm i am writting i will use it to copy some bytes in a specified place in RAM not in a variable or buffer
thanks!
Posted: Thu Apr 03, 2008 9:04 am
by TimB
Remember there are 3 FSR registers, I have not looked at Steves source but I think you will find FRS2 free
Posted: Thu Apr 03, 2008 10:44 am
by Steven
A good point - are there always 3 FSR's, or do some PICs have less?
Posted: Thu Apr 03, 2008 11:04 am
by TimB
The 18 Series always has 3
all you do is change the no at the end 0,1 or 2
Posted: Thu Apr 03, 2008 6:27 pm
by rmteo
Steven wrote:As a guide, the following code takes 18891 bytes of ROM and needs 978 bytes of RAM:
Regards,
Steve
Steve, would it be possible for you to email me the HEX file of the above program - set up for a PIC18F4620, HS Osc at 20Mhz? Thanks.
Posted: Thu Apr 03, 2008 6:59 pm
by Steven
Yes, happily. PM me your email and I'll send it to you.
Posted: Thu Apr 03, 2008 10:19 pm
by rmteo
Thanks for sending the HEX file. I have an EP4 dev board and the mE SD/MMC add-on card. Connections are as follows:
SCK - PORTC.3
MISO - PORTC.4
MOSI - PORTC.5
Chip Select - PORTC.2
Is your HEX set up the same? Right now, the terminal displays:
Insert SD/MMC:
and just stays there.