This application note presents a new SD card library. It is written entirely in BASCOM AVR basic with the intention to minimize RAM usage.
by Niclas Arndt
1 What makes it special?
• Written in commented basic so you can easily understand it and make any addition or modification you see fit. • Low dedicated RAM requirement – read, write, and append with fsinfo updating takes only 651 bytes of RAM plus 10 bytes of $hwstack . Read-only requires only 588 bytes of RAM plus 10 bytes of $hwstack. • An integrated directory scrolling routine useful for forward and backward navigation applications, e.g. mp3 players. • Support for long filenames when scrolling and reading files.
2 Main features
• Modular – you can easily define which parts of the library you want to use. • SDSC, SDHC, and SDXC support. (For SDXC you need to format it with FAT32 in Mac OS or Linux.) • FAT16 and FAT32 support in root directory and subdirectory (no support for ExFAT). • This means that the maximum file size is 4 GB and the maximum partition size is 2 TB. It has been development tested on 32 MB SDSC, 1 GB SDSC, 4 GB SDHC, and 64 GB SDXC. • Find file, subdirectory, parent directory, and volume ID. • Read file with 8.3 or long filename. • Create and write to new file with 8.3 filename. • Create new subdirectory with 8.3 directory name. • Append to a pre-existing file with 8.3 filename. • Scroll forward or backward through a directory. • Update FAT32 fsinfo sector when writing. • Wipe out the contents while maintaining the original formatting.
3 Requirements
• You must use commercial v2.0.5.0 (or higher) of BASCOM AVR. This is because this library requires the new data type DWORD: unsigned 32-bit integer.
4 Table of Contents
1 What makes it special? 2 Main features 3 Requirements 5 What you need to know before you start using the library
5.1 SD card versions and modes 5.2 SD card initialization and identification 5.3 SD card signaling speed. 5.4 Block (sector) size 5.5 Understanding FAT16 and FAT32 5.6 Byte in sector, sector in cluster, cluster, and absolute sector 5.7 Root directory 5.8 FAT, File Allocation Table 5.9 Fsinfo 5.10 Long filenames
6 Using the library
6.1 Configuration 6.2 Knowing your whereabouts 6.3 The root directory 6.4 Creating new files and directories and appending to files
6.4.1 Reading a file 6.4.2 Creating a new file 6.4.3 Creating a new subdirectory 6.4.4 Appending to a pre-existing file
6.5 Write safety vs. performance 6.6 Copying a file or reading and writing concurrently 6.7 Wiping the SD card 6.8 Examples
6.8.1 Initialization sequence
6.8.2 Code size and RAM usage for some of the examples
6.9 Sdstatus
7 General information about BASCOM AVR’s use of RAM
7.1 Hardware Stack 7.2 Software Stack 7.3 Frame 7.4 RAM organization
$regfile = "m644def.dat"
$crystal = 8000000
$framesize = 40 ' This lib only uses ~10 $hwstack - please see the application note for more information
$hwstack = 40 ' This lib only uses ~10 $hwstack - please see the application note for more information
$swstack = 40 ' This lib only uses ~10 $hwstack - please see the application note for more information
$include "KokkeKat_FAT-free_SD_lib_decl.bas"
$include "3310decl.bas" ' <----- This is a display library I used when developing, so it's not required by the SD card lib
' '-------------------------------------------------------------------------------
Dim Sdtempw2 As Word ' Only needed for the example
Dim Sddirentrynameb(12) As Byte ' Only needed for the example
Dim Sddirentrynames As String * 12 At Sddirentrynameb(1) Overlay
' Display initialization
Call D3310reset ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Call D3310init ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Call D3310clear ' <----- This is a display library I used when developing, so it's not required by the SD card lib
' Here starts the mandatory SD card initialization and file system initialization:
Sdstatus = 0
Gosub Sdinit
If Sdstatus = 0 Then ' Initialization succesful. Sdcardtype = 1 -> v1.x SDSC, 2 -> v2+ SDSC, 3 -> v2+ SDHC or SDXC
Gosub Sdinitfs
End If
If Sdstatus = 0 Then
' Here starts the Scroll demo:
' List root directory forward
Sdstartdirclusterd = 0
Sdclusterd = Sdstartdirclusterd
Sddirlistarraycounter = 0
Sddirlistdirection = 0
Do ' Find next 8.3 entry
Gosub Sddirlistloopstep
Loop Until Sdstatus = 32 Or Sddirlistendpoint = 1 ' Loop until EOD marker found or end of directory reached
' List the same directory backward (from the end)
Do ' Find preceding 8.3 entry
Sddirlistdirection = 1
Gosub Sddirlistloopstep
Loop Until Sddirliststartpoint = 1 ' Loop until start of directory reached
End If
End
'-------------------------------------------------------------------------------
Sddirlistloopstep:
Sdstatus = 0
Gosub Sddirlist
If Sdstatus = 26 Or Sdstatus = 27 Then ' File or subdirectory found
Sdlfns = Space(255) ' Clear the name string
Gosub Sdlookforlfn ' See if it has a long file name
If Sdlfnfound = 1 Then ' It has a long filename
Gosub Sdprintlfn
End If
Sddirlistdirection = 0 ' Resume the position at the real 8.3 entry regardless
Do
Sdstatus = 0
Gosub Sddirlist
Loop Until Sdstatus = 26 Or Sdstatus = 27
If Sdlfnfound = 0 Then ' No LFN found - display 8.3 name
Gosub Sdprint83name
End If
Elseif Sdstatus = 34 Then ' Volume ID found
Gosub Sdprint83name
End If
Return
'-------------------------------------------------------------------------------
Sdprintlfn:
Call D3310clear ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Call D3310position(0 , 0) ' <----- This is a display library I used when developing, so it's not required by the SD card lib
For Sdtempw2 = 1 To 40
Sdstr = Chr(sdlfnb(sdtempw2)) ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Call D3310print(sdstr) ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Next Sdtempw2
Wait 1
Return
'-------------------------------------------------------------------------------
Sdprint83name:
Call D3310clear ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Call D3310position(0 , 0) ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Gosub Sdcondense83
For Sdtempw2 = 1 To 12
Sdstr = Chr(sddirentrynameb(sdtempw2)) ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Call D3310print(sdstr) ' <----- This is a display library I used when developing, so it's not required by the SD card lib
Next Sdtempw2
Wait 1
Return
'-------------------------------------------------------------------------------
Sdcondense83:
Sdtempb2 = 9 ' . position
Sdtempb3 = 1 ' Continue marker
Sddirentrynames = Space(12)
For Sdtempb = 8 To 1 Step - 1
Sddirentrynameb(sdtempb) = Sddirlistdirentry(sdtempb)
If Sdtempb3 = 1 And Sddirentrynameb(sdtempb) = &H20 Then
Decr Sdtempb2
Else
Sdtempb3 = 0
End If
Next Sdtempb
If Sddirlistdirentry(9) <> &H20 Or Sddirlistdirentry(10) <> &H20 Or Sddirlistdirentry(11) <> &H20 Then
If Sdstatus = 34 Then
Sdtempb2 = 9
Else
Sddirentrynameb(sdtempb2) = &H2E
Incr Sdtempb2
End If
Sddirentrynameb(sdtempb2) = Sddirlistdirentry(9)
Incr Sdtempb2
Sddirentrynameb(sdtempb2) = Sddirlistdirentry(10)
Incr Sdtempb2
Sddirentrynameb(sdtempb2) = Sddirlistdirentry(11)
End If
Return
'===============================================================================
$include "KokkeKat_FAT-free_SD_lib_code.bas"
$include "3310endshiftout.bas" ' <----- This is a display library I used when developing, so it's not required by the SD card lib |