' KokkeKat FAT-free SD library declarations for SDSC, SDHC, and SDXC - INCLUDE at the beginning of your code
' Written by Niclas Arndt, Stockholm, Sweden, 2011.05.06
' License terms apply, as stated in the application note
' Developer switches:
' 1 = minimum detail (only make sure that the init is successful)
' 0 = full detail (return full detail if init is unsuccessful)
Const Sdinitdetail = 1
' 1 = FAT16/32 file system active
' 0 = FAT16/32 file system not active (only read and write raw sectors)
Const Sdfsactive = 1
' 1 = Use the FIND routine
' 0 = Don't use the FIND routine
Const Sdusefind = 0
' 1 = Enable Sdusefindstoreentry
' 0 = Don't enable Sdusefindstoreentry
Const Sdusefindstoreentry = 0
' 1 = Use Sddirlist
' 0 = Don't use Sddirlist
Const Sdusedirlist = 1 ' Use or don't use
Const Sddirlistarraysize = 12 ' If used, set the size of the array that holds the cluster numbers
' 1 = read
' 0 = not reading
Const Sdrmode = 1
' 2 = write unbuffered
' 1 = write buffered
' 0 = not writing
Const Sdwmode = 1
' 1 = Use Sdappend
' 0 = Don't use Sdappend
Const Sduseappend = 1
' 1 = Clear the unused end of the sector before writing it to the SD card
' 0 = Don't clear the unused end of the sector before writing it to the SD card
Const Sdcleartail = 0
' 1 = Use FAT32 fsinfo sector data
' 0 = Don't use FAT32 fsinfo sector
Const Sdusefsinfo = 1
' 1 = Use Long FileNames when reading
' 0 = Don't use Long FileNames when reading
Const Sduselfn = 0
' 1 = When using lfn, also support file name comparison
' 0 = When using lfn, don't support file name comparison
Const Sduselfncompare = 0
' 1 = Use wipe
' 0 = Don't use wipe
Const Sdusewipe = 1
' 1 = Use the size info routine
' 0 = Don't use the size info routine
Const Sdusesizeinfo = 1
' 1 = Use the CRC7 function
' 0 = Don't use the CRC7 function
Const Sdusecrc7 = 0 ' This has no practical use in the library - use it if you want to add CRC7 checks yourself
'===============================================================================
' Sdstatus codes:
' 0 = Success (no error found)
' 1 = Timeout at initialization CMD0
' 2 = Timeout at initialization CMD8
' 3 = Timeout at initialization first CMD58
' 4 = Timeout at initialization CMD55 + ACMD41 loop
' 5 = Timeout at initialization second CMD58
' 6 = Timeout at CMD13
' 7 = Timeout while waiting for &H00 &HFE
' 8 = Minimum initialization detail unspecified error 1
' 9 = Minimum initialization detail unspecified error 2
' 10 = R1 idle (running initialization)
' 11 = R1 erase reset
' 12 = R1 illegal command
' 13 = R1 command CRC error
' 14 = R1 erase sequence error
' 15 = R1 address error
' 16 = R1 parameter error
' 17 = R3 not an SD card
' 18 = R3 supply voltage out of bounds
' 19 = R7 unsupported voltage or VHS error in CMD8 command
' 20 = R7 unspecified error in CMD8 response
' 21 = Unsupported FAT32 root cluster number (not 2)
' 22 = R3 card power up busy (OCR.31 = 0)
' 23 = Not supported file system
' 24 =
' 25 =
' 26 = A file entry has been found
' 27 = A directory entry has been found
' 28 = An available (previously erased) directory space has been found
' 29 = Unsupported number of sectors per cluster
' 30 =
' 31 = EOC End Of Cluster chain marker found
' 32 = EOD End Of Directory marker found
' 33 = Subdirectory . or .. entry found
' 34 = The volume ID has been found
' 35 = Unsupported sector size
' 36 = Long file name found
' 37 =
' 38 =
' 39 =
' 40 =
' 41 = Data rejected due to a CRC error
' 42 = Data rejected due to a Write Error
' 43 = Free FAT entry found
' 44 = End of FAT and no free entry found (partition full)
' 45 =
' 46 = We have searched the entire FAT16 root directory but not found what we were looking for
' 47 = Parent directory pointer found
' 48 = File or subdirectory found
' Status bits:
' Sdeof: 1 = EOF marker
' Sdreaddestination 0 = Sdbuffer, 1 = Sdfat1buffer
' Sdwriteorigin 0 = Sdbuffer, 1 = Sdfat1buffer
' Sdcreatemode 0 = file, 1 = subdirectory
' Sdclosefile 1 = close the current file
' Sdpartitionfull 1 = the partition is full (no more free FAT entries)
' Sdsavedatasector 1 = save the current data sector
' Sdfatcontinue 1 = continue looping through the current FAT sector
' Sddirlistdirection 0 = forward, 1 = backward
' Sddirliststartpoint 1 = the directory backward listing has reached the starting point
' Sddirlistendpoint 1 = the directory forward listing has reached the end point
' Sddirlistoutside 1 = we are outside of the directory cluster array when listing the directory
' Sdlfncontinue 1 = continuing assembling or printing the long filename
' Sdlfnfound 1 = last directory entry of a long filename found
' Sdappendcontinue 1 = continue comparing the filename
' Sdappendfound 1 = the file has been found
' Sderaseall 1 = erase all data sectors as well
'===============================================================================
' SPI declaration : auch anders im Hauptprogramm definiert!
Config Portb.4 = Output ' The !SS pin can only be used as an output in SPI hardware master mode)
Sd_cs Alias Portb.4
Config Portb.5 = Output
Sd_di Alias Portb.5 ' MOSI
Config Portb.7 = Output
Sd_clk Alias Portb.7 ' Clock
Config Portb.6 = Input
Sd_do Alias Portb.6 ' MISO
'(
' HW SPI - make sure that your initial clock frequency <= 400 kHz
' After initialization, try to increase the speed and also set the SPCR register to double speed
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 64 , Noss = 1 , Spiin = 255
'Spcr = &B010
Spiinit ' Init SPI
')
Dim Sdcommand As Byte ' The bytewise 8 to 48-bit command to SD
Dim Sdresponse(6) As Byte ' The <= 48-bit response from SD
Dim Sdstatus As Byte ' Status after gosub
Dim Sdcardtype As Byte ' 1 = v1.x SDSC, 2 = v2+ SDSC, 3 = v2+ SDHC
Dim Sdtempb As Byte ' Generic loop variables
Dim Sdtempb2 As Byte
Dim Sdtempb3 As Byte
Dim Sdtempwb(2) As Byte
Dim Sdtempw As Word At Sdtempwb(1) Overlay
Dim Sdsectorb(4) As Byte
Dim Sdsectord As Dword At Sdsectorb(1) Overlay ' Sector number for read/write
Dim Sdexpectedresponse As Byte ' The byte value we are waiting for after a CMD17
Dim Sdbuffer(512) As Byte ' The 512 byte array that is filled when reading data from SD
#if Sdfsactive = 1
Const Sdbytespersecw = 512 ' The only supported sector size
Dim Sdfattype As Byte ' FAT16 = 2 or FAT32 = 4 as derived from the partition type. FAT record = 2 bytes for FAT16 and 4 bytes for FAT32.
#if Sdusewipe = 1
Dim Sdpartstart As Dword ' The absolute sector number for the partition start
Dim Sdtotsecsb(4) As Byte
Dim Sdtotsecsd As Dword At Sdtotsecsb(1) Overlay ' The relative number of sectors in this partition (starting with Sdpartstart)
' Number of sectors in partition, including all 4 regions:
' 0 - Reserved Region
' 1 - FAT Region
' 2 - Root Directory Region (doesn't exist on FAT32 volumes)
' 3 - File and Directory Data Region
#endif
' Dim Sdfat32rootclusterb(4) As Byte
' Dim Sdfat32rootclusterd As Dword At Sdfat32rootclusterb(1) Overlay ' Cluster number for the FAT32 root (normally 2 but could be higher (e.g. in case of bad cluster))
Const Sdfat32rootclusterd = 2
Dim Sdfat1location As Dword ' FAT1 location (sector number)
Dim Sdfat2location As Dword ' FAT2 location (sector number)
Dim Sdrootdirlocation As Dword ' FAT16 root dir location (sector number)
Dim Sdsecsinroot As Word ' Number of sectors in FAT16 root dir
Dim Sdsecspercluster As Byte ' Sectors per cluster
Dim Sdsectorend As Word ' Assigned from Sdsecspercluster or Sdsecsinroot and serves as the final sector in the cluster or root
Dim Sdsecincluster As Word ' Current sector number of the current cluster, 1 to Sdsecincluster (defined as word to have place for Sdsecsinroot)
Dim Sddataareastart As Dword ' Sector number for start of data, cluster 2
Dim Sdtempdb(4) As Byte
Dim Sdtempd As Dword At Sdtempdb(1) Overlay ' Generic loop/temp variable
Dim Sdclusterb(4) As Byte
Dim Sdclusterd As Dword At Sdclusterb(1) Overlay ' Current cluster number
Dim Sdbufferpos As Word ' Current buffer position, 1 to 512
Dim Sdfilesizeb(4) As Byte
Dim Sdfilesized As Dword At Sdfilesizeb(1) Overlay ' File size in bytes
Dim Sdbyterw As Byte ' The byte that is read or written
Dim Sdbytesread As Dword ' Counter for the number of read bytes
#endif
#if Sdusefsinfo = 1
Dim Sdfat32fsinfolocationb(4) As Byte
Dim Sdfat32fsinfolocationw As Dword At Sdfat32fsinfolocationb(1) Overlay ' Sector number for the FAT32 fsinfo (Could probably use word - dword used for partition offset)
Dim Sdfsinfofreeclustersb(4) As Byte
Dim Sdfsinfofreeclustersd As Dword At Sdfsinfofreeclustersb(1) Overlay ' Number of free clusters according to the FAT32 fsinfo
Dim Sdfsinfonextfreeclusterb(4) As Byte
Dim Sdfsinfonextfreeclusterd As Dword At Sdfsinfonextfreeclusterb(1) Overlay ' Number of next free cluster according to the FAT32 fsinfo
#endif
#if Sdwmode = 1
Dim Sdfatbuffer(512) As Byte ' The 512 byte array that is filled when reading data from SD
#endif
#if Sdwmode > 0 And Sdfsactive = 1
Dim Sdpreviousclusterb(4) As Byte ' Previous cluster number
Dim Sdpreviousclusterd As Dword At Sdpreviousclusterb(1) Overlay
Dim Sddirclusterb(4) As Byte
Dim Sddirclusterd As Dword At Sddirclusterb(1) Overlay ' Current directory cluster number
Dim Sddirsecincluster As Word ' Chain start sector number of the current directory cluster, 1 to Sdsecincluster
Dim Sddirbufferpos As Word ' Chain start directory buffer position, 1 to 512
Dim Sdwclusterb(4) As Byte ' The cluster number being written
Dim Sdwclusterd As Dword At Sdwclusterb(1) Overlay
Dim Sdwsecincluster As Byte ' The sector number in the current cluster being written
'Dim Sdwbufferposb(2) As Byte
Dim Sdwbufferpos As Word 'At Sdwbufferposb(1) Overlay ' The byte number in the current sector being written
Dim Sdwfilesizeb(4) As Byte
Dim Sdwfilesized As Dword At Sdwfilesizeb(1) Overlay ' Write file size in bytes
Dim Sdfatclusterb(4) As Byte ' Stores the FAT1 entry's corresponding cluster number (not the pointer to the next entry)
Dim Sdfatclusterd As Dword At Sdfatclusterb(1) Overlay
Dim Sdfatsectornum As Dword ' FAT1 absolute sector number - stores the current FAT sector number
Dim Sdfatbufferpos As Word ' Buffer position in Sdfatsector - stores the buffer position in the current FAT sector
' DateTime variables
Dim Sdday As Byte
Dim Sdmonth As Byte
Dim Sdyear As Word
Dim Sdmseconds As Byte
Dim Sdseconds As Byte
Dim Sdminutes As Byte
Dim Sdhours As Byte
Dim Sddateb(2) As Byte ' Date variable for the directory entry DateTime
Dim Sddatew As Word At Sddateb(1) Overlay
Dim Sdtimeb(2) As Byte ' Time variable for the directory entry DateTime
Dim Sdtimew As Word At Sdtimeb(1) Overlay
#endif
#if Sdusefind = 1
Dim Sddirectorymode As Byte ' 0 = find file, 1 = find subdirectory, 2 = find volume ID, 3 = find available directory entry, 4 = find parent directory, 5 = return entire entry unless EOD
#if Sdusefindstoreentry = 1
Dim Sdfinddirentry(32) As Byte ' An entire directory entry
#endif
#endif
#if Sdusedirlist = 1 Or Sdwmode > 0
#if Sdfsactive = 1
Dim Sdstartdirclusterb(4) As Byte ' Directory chain start cluster number
Dim Sdstartdirclusterd As Dword At Sdstartdirclusterb(1) Overlay
#endif
#endif
#if Sdusedirlist = 1 Or Sdusefind = 1
Dim Sdentrynames As String * 11 ' 8.3 file or subdirectory name without the dot
Dim Sdentrynameb(11) As Byte At Sdentrynames Overlay
#endif
#if Sdusedirlist = 1
Dim Sddirlistarray(sddirlistarraysize) As Dword ' The array
Dim Sddirlistarraypointer As Byte ' The pointer of where we are in the array of already found directory clusters (useful when going backwards and then forward)
'Dim Sddirlistarraypointer As Word
Dim Sddirlistarraycounter As Byte ' Keeps track of how many clusters exist in the array
'Dim Sddirlistarraycounter As Word
Dim Sddirlistnextclusterb(4) As Byte ' Next or previous FAT cluster number
Dim Sddirlistnextclusterd As Dword At Sddirlistnextclusterb(1) Overlay
Dim Sddirlistcurrclusterb(4) As Byte ' Current FAT cluster number
Dim Sddirlistcurrclusterd As Dword At Sddirlistcurrclusterb(1) Overlay
Dim Sddirlistdirentry(32) As Byte ' Holds one directory entry at the time
' Dim Sdtempw2 As Word ' Generic temp/loop variable (used in the example code)
#endif
#if Sduselfn = 1
Dim Sdlfns As String * 255 ' Return variable for the long filename
Dim Sdlfnb(255) As Byte At Sdlfns Overlay
Dim Sdlfnchecksum As Byte ' 8.3 filename checksum
Dim Sdtempb4 As Byte ' Generic loop / temp variable
Dim Sdlfndirentry(32) As Byte ' Holds one directory entry at the time
#if Sduselfncompare = 1
Dim Sdlfn2s As String * 255 ' Compare variable for the long filename
Dim Sdlfn2b(255) As Byte At Sdlfn2s Overlay
#endif
#endif
#if Sdusesizeinfo = 1
Dim Sdcsize As Long
Dim Sdcsizemult As Byte
Dim Sdreadbllen As Byte
#endif
#if Sdusecrc7 = 1
Declare Function Sdcrc7(byval Sdarray As Byte) As Byte
Dim Sdcrc7byte As Byte
#endif
#if Sdwmode > 0 And Sdfsactive = 1
Dim Sdcreatemode As Bit ' 0 = file, 1 = subdirectory
Dim Sdclosefile As Bit ' 1 = close the current file
Dim Sdpartitionfull As Bit ' 1 = the partition is full (no more free FAT entries)
Dim Sdsavedatasector As Bit ' 1 = save the current data sector
Dim Sdfatcontinue As Bit ' 1 = continue looping through the current FAT sector
#endif
#if Sdwmode = 1 And Sdfsactive = 1
Dim Sdreaddestination As Bit ' 0 = Sdbuffer, 1 = Sdfat1buffer
Dim Sdwriteorigin As Bit ' 0 = Sdbuffer, 1 = Sdfat1buffer
#endif
#if Sdrmode = 1
Dim Sdeof As Bit ' EOF marker
#endif
#if Sdusedirlist = 1
Dim Sddirliststartpoint As Bit ' 1 = the directory backward listing has reached the starting point
Dim Sddirlistendpoint As Bit ' 1 = the directory forward listing has reached the end point
Dim Sddirlistdirection As Bit ' 0 = forward, 1 = backward
Dim Sddirlistoutside As Bit ' 1 = we have scrolled outside of Sddirlistarray() array
#if Sduseappend = 1
Dim Sdappendcontinue As Bit ' 1 = continue comparing the filename
Dim Sdappendfound As Bit ' 1 = the file has been found
#endif
#endif
#if Sduselfn = 1
Dim Sdlfncontinue As Bit ' 1 = continuing assembling the long filename
Dim Sdlfnfound As Bit ' 1 = last directory entry of a long filename found
#endif
#if Sdusewipe = 1
Dim Sderaseall As Bit ' 1 = erase all data sectors as well
#endif