I ran into problem with the modification I did for the SD module (originated from Steven).
I tried reading 4 sectors from the SD card and load them into an array of buffers. These buffer are declared as public array as FShared(5). I thought by modifying the ReadSector subroutine as follow will do. It may not be the correct way.
Initially it worked well. But later I realized that the modification will not work if I read more than 1 sector at a time. Can anyone suggest a correct way to do it? And point out where I went wrong? I am thinking of doing it in the shortest time so, I put everything into one call to the subroutine.
Code: Select all
Public Dim FShared(5) As TShared
...
...
Public Sub FReadSector(ByRef pSector As LongWord, pBuffer As Boolean = True)
Dim TimeOut, Error As Byte
Dim Index As Word
Clear(FShared(1))
Clear(FShared(2))
Clear(FShared(3))
Clear(FShared(4))
'have to do like this, since SF does not allow us to use array in memory indexing
#if SectorToRead >= 1
If (Disk.RWError = True And pBuffer) Then // If RW error has occurred, prevent further reading from
// disk until reinitialised, unless not buffering
// (pBuffer = False, used for DiskMounted)
Exit
EndIf
TimeOut = $00
Error = 1
If (Disk.CardType And $04) = 0 Then // MMC or SD - byte addressing (SDHC use block addressing)
pSector = pSector << 9
EndIf
Repeat
CS = 0
If SendCmd(CMD17, pSector) = $00 Then // Send Cmd 17
If SeekResponse($FE) = $FE Then // Read start token
Index = 0
If pBuffer Then
FSR0 = @FShared(1).CurrentSectorBuffer
Repeat // Read data block
#if SD_SPI = SW // Software SPI version - use SendByte
POSTINC0 = ReceiveByte()
#elseif SD_SPI = MSSP // MSSP version - use inline routine to optimise speed
SSPIF = 0
SSPBuffer = $FF
Repeat
ClrWDT
Until SSPIF = 1
POSTINC0 = SSPBuffer
#endif
Inc(Index)
Until Index = $200
Else
Repeat // Don't read data block
ReceiveByte()
Inc(Index)
Until Index = $200
EndIf
ReceiveByte() // Read dummy CRC to conclude data block
ReceiveByte()
Error = 0 // Read completed successfully
EndIf
EndIf
CS = 1
SendByte($FF) // Clock SD/MMC to complete read
Inc(TimeOut)
Until Error = 0 Or TimeOut > $01
If Error = 1 Then
Disk.RWError = True // Set RWError flag - can only be cleared using Init()
EndIf
#endif
#if SectorToRead >= 2
'2nd Buffer
Inc(pSector) // Move to next Sector and next buffer
If (Disk.RWError = True And pBuffer) Then // If RW error has occurred, prevent further reading from
// disk until reinitialised, unless not buffering
// (pBuffer = False, used for DiskMounted)
Exit
EndIf
TimeOut = $00
Error = 1
If (Disk.CardType And $04) = 0 Then // MMC or SD - byte addressing (SDHC use block addressing)
pSector = (pSector << 9)
EndIf
Repeat
CS = 0
If SendCmd(CMD17, pSector) = $00 Then // Send Cmd 17
If SeekResponse($FE) = $FE Then // Read start token
Index = 0
If pBuffer Then
FSR0 = @FShared(2).CurrentSectorBuffer
Repeat // Read data block
#if SD_SPI = SW // Software SPI version - use SendByte
POSTINC0 = ReceiveByte()
#elseif SD_SPI = MSSP // MSSP version - use inline routine to optimise speed
SSPIF = 0
SSPBuffer = $FF
Repeat
ClrWDT
Until SSPIF = 1
POSTINC0 = SSPBuffer
#endif
Inc(Index)
Until Index = $200
Else
Repeat // Don't read data block
ReceiveByte()
Inc(Index)
Until Index = $200
EndIf
ReceiveByte() // Read dummy CRC to conclude data block
ReceiveByte()
Error = 0 // Read completed successfully
EndIf
EndIf
CS = 1
SendByte($FF) // Clock SD/MMC to complete read
Inc(TimeOut)
Until Error = 0 Or TimeOut > $01
If Error = 1 Then
Disk.RWError = True // Set RWError flag - can only be cleared using Init()
EndIf
#endif
#if SectorToRead >= 3
'3rd buffer
Inc(pSector)
If (Disk.RWError = True And pBuffer) Then // If RW error has occurred, prevent further reading from
// disk until reinitialised, unless not buffering
// (pBuffer = False, used for DiskMounted)
Exit
EndIf
TimeOut = $00
Error = 1
If (Disk.CardType And $04) = 0 Then // MMC or SD - byte addressing (SDHC use block addressing)
pSector = pSector << 9
EndIf
Repeat
CS = 0
If SendCmd(CMD17, pSector) = $00 Then // Send Cmd 17
If SeekResponse($FE) = $FE Then // Read start token
Index = 0
If pBuffer Then
FSR0 = @FShared(3).CurrentSectorBuffer
Repeat // Read data block
#if SD_SPI = SW // Software SPI version - use SendByte
POSTINC0 = ReceiveByte()
#elseif SD_SPI = MSSP // MSSP version - use inline routine to optimise speed
SSPIF = 0
SSPBuffer = $FF
Repeat
ClrWDT
Until SSPIF = 1
POSTINC0 = SSPBuffer
#endif
Inc(Index)
Until Index = $200
Else
Repeat // Don't read data block
ReceiveByte()
Inc(Index)
Until Index = $200
EndIf
ReceiveByte() // Read dummy CRC to conclude data block
ReceiveByte()
Error = 0 // Read completed successfully
EndIf
EndIf
CS = 1
SendByte($FF) // Clock SD/MMC to complete read
Inc(TimeOut)
Until Error = 0 Or TimeOut > $01
If Error = 1 Then
Disk.RWError = True // Set RWError flag - can only be cleared using Init()
EndIf
#endif
#if SectorToRead = 4
'4th sector
Inc(pSector)
If (Disk.RWError = True And pBuffer) Then // If RW error has occurred, prevent further reading from
// disk until reinitialised, unless not buffering
// (pBuffer = False, used for DiskMounted)
Exit
EndIf
TimeOut = $00
Error = 1
If (Disk.CardType And $04) = 0 Then // MMC or SD - byte addressing (SDHC use block addressing)
pSector = pSector << 9
EndIf
Repeat
CS = 0
If SendCmd(CMD17, pSector) = $00 Then // Send Cmd 17
If SeekResponse($FE) = $FE Then // Read start token
Index = 0
If pBuffer Then
FSR0 = @FShared(4).CurrentSectorBuffer
Repeat // Read data block
#if SD_SPI = SW // Software SPI version - use SendByte
POSTINC0 = ReceiveByte()
#elseif SD_SPI = MSSP // MSSP version - use inline routine to optimise speed
SSPIF = 0
SSPBuffer = $FF
Repeat
ClrWDT
Until SSPIF = 1
POSTINC0 = SSPBuffer
#endif
Inc(Index)
Until Index = $200
Else
Repeat // Don't read data block
ReceiveByte()
Inc(Index)
Until Index = $200
EndIf
ReceiveByte() // Read dummy CRC to conclude data block
ReceiveByte()
Error = 0 // Read completed successfully
EndIf
EndIf
CS = 1
SendByte($FF) // Clock SD/MMC to complete read
Inc(TimeOut)
Until Error = 0 Or TimeOut > $01
If Error = 1 Then
Disk.RWError = True // Set RWError flag - can only be cleared using Init()
EndIf
#endif
'push the lead pSector value to next
Inc(pSector) 'pass by reference
End Sub
Thanks.
Regards,
Liak.