I don't have any idea, but this is the library:Zsola wrote:Hello Yo2ilo, Dany says I should ask you about SDMMC_SPI2.
My code is here: http://www.mikroe.com/forum/viewtopic.p ... 53#p124253
Can you help me, whats the problem with this?
Code: Select all
unit SDMMC_SPI2;
function SDMMC_Init : boolean;
function SDMMC_ReadSector(Sector : dWord; var MMC_Buffer : array[512] of byte) : boolean;
function SDMMC_WriteSector(Sector : dWord; var MMC_Buffer : array[512] of byte) : boolean;
const CMD0 = $40 + 0; // GO_IDLE_STATE
CMD1 = $40 + 1; // SEND_OP_COND
CMD8 = $40 + 8; // SEND_IF_COND
CMD9 = $40 + 9; // SEND_CSD
CMD10 = $40 + 10; // SEND_CID
CMD12 = $40 + 12; // STOP_TRANSMISSION
CMD16 = $40 + 16; // SET_BLOCKLEN
CMD17 = $40 + 17; // READ_SINGLE_BLOCK
CMD18 = $40 + 18; // READ_MULTIPLE_BLOCK
CMD23 = $40 + 23; // SET_BLOCK_COUNT
CMD24 = $40 + 24; // WRITE_BLOCK
CMD25 = $40 + 25; // WRITE_MULTIPLE_BLOCK
CMD41 = $40 + 41; // SEND_OP_COND (ACMD)
CMD55 = $40 + 55; // APP_CMD
CMD58 = $40 + 58; // READ_OCR
TimeOutLimit = 10000; // Set timeout limit based on clock
sdMMC = 1; // Multi Media Card (MMC)
sdSD = 2; // Secure Digital Card (SD)
sdSDHC = 4; // High Capacity Secure Digital Card (SDHC)
var SDMMC_CS : sbit; sfr; external;
SDMMC_CS_dir : sbit; sfr; external;
cardtype : byte;
implementation
procedure SDMMC_Write(tx_data : byte);
begin
asm
MOVF SSP2BUF,W
end;
SSP2BUF := tx_data;
ClrWdt;
while SSP2STAT.BF = 0 do;
asm
MOVF SSP2BUF,W
end;
end;
procedure SDMMC_Read;
begin
asm
MOVF SSP2BUF,W
SETF SSP2BUF
end;
ClrWdt;
while SSP2STAT.BF = 0 do;
asm
MOVFF SSP2BUF,R18
end;
end;
function SeekResponse(Required : Byte) : Byte;
var Index : Word;
begin
Index := 0;
while Index < $FFFF do
begin
SDMMC_Read;
result := R18;
if result = Required then break;
inc(Index);
end;
end;
function SendCmd(Cmd : Byte; Arg : dWord) : Byte;
var CRC,index : Byte;
begin
if SeekResponse($FF) <> $FF then result := $FF // wait for ready
else
begin
SDMMC_Write(Cmd); // Command
SDMMC_Write(Highest(Arg)); // Argument[31..24]
SDMMC_Write(Higher(Arg)); // Argument[23..16]
SDMMC_Write(Hi(Arg)); // Argument[15..08]
SDMMC_Write(Lo(Arg)); // Argument[07..00]
CRC := $FF; // Default CRC byte
if Cmd = CMD0 then CRC := $95 // CRC for CMD0($0)
else if Cmd = CMD8 then CRC := $87; // CRC for CMD8($1AA)
SDMMC_Write(CRC);
Index := 0;
while Index < 100 do
begin // Receive command response
inc(index);
SDMMC_Read;
result := R18;
if (result and $80) < 2 then break; // Wait for a valid response in timeout of 100 attempts
end;
end;
end;
function SDMMC_ReadSector(Sector : dWord; var MMC_Buffer : array[512] of byte) : boolean;
var TimeOut : Byte;
Index : Word;
begin
result := false;
if cardtype = 0 then exit;
TimeOut := 0;
if (cardtype and $04) = 0 then Sector := Sector shl 9; // MMC or SD - byte addressing (SDHC use block addressing)
while result = false do
begin
SDMMC_CS := 0;
nop;
nop;
if SendCmd(CMD17, Sector) = $00 then // Send Cmd 17
if SeekResponse($FE) = $FE then // Read start token
begin
Index := 0;
FSR2 := word(@MMC_Buffer);
while Index < 512 do // Read data block
begin
SDMMC_Read;
POSTINC2 := R18;
Inc(Index);
end;
SDMMC_Read; // Read dummy CRC to conclude data block
SDMMC_Read;
result := true; // Read completed successfully
end;
SDMMC_CS := 1;
nop;
nop;
SDMMC_Read; // Clock SD/MMC to complete read
if Inc(TimeOut) > 1 then break
end;
end;
function SDMMC_WriteSector(Sector : dWord; var MMC_Buffer : array[512] of byte) : boolean;
var Response : Byte;
Index : Word;
TimeOut : Byte;
begin
result := false;
if cardtype = 0 then exit;
TimeOut := $00;
if (cardtype and $04) = 0 then Sector := Sector shl 9; // MMC or SD - byte addressing (SDHC use block addressing)
while result = false do
begin
SDMMC_CS := 0;
nop;
nop; // Send Cmd 24
if SeekResponse($FF) = $FF then // Wait for ready
if SendCmd(CMD24, Sector) = $00 then
begin
SDMMC_Write($FE); // Write start token
Index := 0;
FSR2 := word(@MMC_Buffer);
while Index < 512 do // Write data block
begin
SDMMC_Write(POSTINC2);
Inc(Index);
end;
SDMMC_Read; // Send dummy CRC to conclude data block
SDMMC_Read;
SDMMC_Read;
Response := R18; // Data response token
Response := Response and $1F;
if Response = $05 then result := true;
end;
SDMMC_CS := 1;
nop;
nop;
SDMMC_Read; // Complete SPI transaction
if Inc(TimeOut) > 10 then break;
end;
end;
function Cmd5541(BitSet : Boolean) : Byte;
begin
result := SendCmd(CMD55, 0);
if result > 1 then Exit
else
begin
if BitSet = true then result := SendCmd(CMD41, $40000000)
else result := SendCmd(CMD41, 0);
end;
end;
function SDMMC_Init_ : boolean;
var Index : Word;
OCR : array[4] of Byte;
tmp : string[2];
begin
result := true;
cardtype := 0;
SDMMC_CS := 1; // Pull CS high
SDMMC_CS_dir := 0;
Index := 0;
while Index < 20 do // Clock SD for min 80 cycles
begin
SDMMC_Read;
inc(Index);
end;
SDMMC_CS := 0; // Pull CS low
nop;
nop;
if SendCmd(CMD0, 0) = $01 then // Send Cmd 0 - enter idle state
if SendCmd(CMD8, $01AA) = $01 then // SDC Version 2+
begin
for Index := 0 To 3 do
begin
SDMMC_Read;
OCR[Index] := R18;
end;
if (OCR[2] = $01) and (OCR[3] = $AA) then // SD Vdd range of 2.7 - 3.6 volts
begin
Index := TimeOutLimit;
while Index > 0 do
begin
dec(Index);
if Cmd5541(True) = 0 then break;
end;
if Index > 0 then // Cmd 55/41 successful with HCS bit set
if SendCmd(CMD58, 0) = 0 then // Send Cmd 58
begin
for Index := 0 To 3 do
begin
SDMMC_Read;
OCR[Index] := R18;
end;
// CCS[30] bit in the OCR set
if (OCR[0] and $40) > 0 then cardtype := sdSDHC // Init successful - SDHC (3)
else cardtype := sdSD; // Init successful - SD (2)
end;
end
end
else // SD Version 1 or MMC
begin
if Cmd5541(False) <= 1 then
begin
cardtype := sdSD; // Init successful - SD (2)
Index := TimeOutLimit;
while Index > 0 do
begin
dec(Index);
if Cmd5541(True) = 0 then break;
end;
end // Wait for leaving idle state
else
begin
cardtype := sdMMC; // Init successful - MMC (1)
Index := TimeOutLimit;
while Index > 0 do
begin
dec(Index);
if SendCmd(CMD1, 0) = 0 then break; // Wait for leaving idle state
end;
end;
end;
if Index = 0 then result := false
else SendCmd(CMD16, $0200);
SDMMC_CS := 1;
nop;
nop;
SDMMC_Read; // Clock SD/MMC to complete
end;
function SDMMC_Init : boolean;
var Index : byte;
begin
Index := 0;
while Index < 10 do
begin
result := SDMMC_Init_;
if cardtype <> 0 then break;
inc(index);
end;
if cardtype <> 0 then result := true;
end;
end.