Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Write block (512 Bytes) to the MMC

Status
Not open for further replies.

SISWANTO

Advanced Member level 4
Joined
May 14, 2001
Messages
107
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,298
Location
Nirwana
Activity points
877
multimedia card image file

Dear all,
I developing project use MMC, I had successfully to do reset and initialize the MMC, but when i want to write-block (CMD24) to the MMC, the response-data is strange, it is 0xE0 (the correct one is 0xE5). any one can help me, what mistake??


thanks
Siswa
 

multimedia card image file proteus

First check your power supply voltage for MMC also add some blocking caps if you using MMC with MCU..
 

mmc proteus

Make sure you adjust packet size to 512 bytes....

Initialize_MMC();
MMC_PacketSize(2,0); //512 Byte
MMC_SELECT;


void MMC_PacketSize(char packetmsb,char packetlsb)
{
PRT0DR &= ~0x04; //enable MMC
delay50ms();
SPISend(0x40 | 16,0x00,0x00,packetmsb,packetlsb,0x95); // Set block length for 128 byte data transfer
response=SPIM_1_bReadRxData();
PRT0DR |= 0x04; //enable MMC
delay50ms();
}


Soon , all codes wll be available free at electronicsclub.net (not yet open at the moment: 23 Dec 2004 , check after 4th week of Jan 2005 )
 

rabbit 2000

try proteus mmc model. it logs commands and some errors.

Added after 3 minutes:
 
how to block mmc

Hi Free_Will,
I need sample code early, could you give your code to me??, to long time waiting for put your code in electronicsclub.net. it is around 1 month.


Siswa
 

bascom mmc

I have source code for MMC in SPI Mode to AVR. I can send you if intrested.
 

simulação mmc proteus

Hi Asit,
Please send to me Your source code, no problem it is for AVR, I can do porting to rabbit (I using rabbit microprocessor). Btw, is Your code written ic C??, because if in assembly, it is too hard to do porting.
You can upload to this board ( it will jack-up your point) or You can send to my email address
gumbreg@yahoo.com


Sisw
 

mmc in proteus

SISWANTO said:
Hi Asit,
Please send to me Your source code, no problem it is for AVR, I can do porting to rabbit (I using rabbit microprocessor). Btw, is Your code written ic C??, because if in assembly, it is too hard to do porting.

How do you get rabbit micros in indonesia?

And about MMCs, please post any working codes/links in this forum. I need it for my project too :D
 

mmc con proteus no responde

I get rabbit microprocessor direct from www.rabbitsemi.com, because rabbit do not sell it freely in the free market. Every one who want use rabbit microprocessor, must buy compiler (dinamic C) first. and every re-order MCU, they will cross-match your customer-number with them customer-database. if you do not have a customer-number, You will never get the MCU.

About MMC:
I have done successfully to do reset and initialize the MMC, but when i want to write/read, i get uncorrect response.



Sisw
 

avr mmc bascom

Hi ilker and All,
I have done simulate MMC using proteus + MMC model from
**broken link removed**, but the result is the same,
with when i use real hardware.
Reset and initialization to the MMC always successfull, but when
I wanna read MMC I never get correct DATA-TOKEN (0xFE).
My screenshoot of proteus and my source code (CodevisionAVR)
attached, please help me.


Siswa
 

proteus+mmc image file

asit said:
I have source code for MMC in SPI Mode to AVR. I can send you if intrested.


Hello asit.
I would like to see your code, I am developing a proyect and I think it could be really useful. Thanks.
daniel_sauceda@yahoo.com
 

mmc bascom command

I have got a few requests for the BASCOM Code for interfacing MMC to AVR. So, I am posting it here.

It uses the hardware SPI of ATMEGA162.
I only use 212 bytes of each sector, you can modify it for 512 bytes.

For all the commands, store adr (address) and call the routine.
Readsector reads the sector specified in adr into indat
write sector writes Indat to specified adr.

No FAT support only direct reading and writing.

Refer to sandisk application note for further commands.

Use appropriate level converters if you run the micro at 5 volt as MMC only runs on 3.3 volts. A 100 pF bypass cap on the clock line works like wonder for intermittant init problems.

I havn't used this code since a long time. If anybody has corrections/modifications/suggestions pleas post it.

Regards.


Cs Alias Portb.4
Ddrb.1 = 1
Ddrb.4 = 1
Ddrb.5 = 1
Ddrb.6 = 0
Ddrb.7 = 1

Dim Indat(212) As Byte At 256

'MMC commnd
Dim Command(6) As Byte At 470 ' 358 '&H100
Dim Comm As Byte At 470 Overlay '358 &H100 Overlay
Dim Adr As Long At 471 Overlay '359&H101 Overlay
Dim Trail As Byte At 475 Overlay '363 &H105 Overlay

**************************************************************************
'**************************************************************************
'Spcr = &B01011100 'This is the MMC power spi
Spcr = &B01011101 'last 01 = f/16 00 =f/4
Spsr = 0
Declare Sub Getresp
Declare Sub Spiwait
Declare Sub Sendbyte
Declare Sub Sendcmd
Declare Sub Readbyte
Declare Sub Readsector
Declare Sub Writesector
Declare Sub Mmcinit

Declare Sub Cardformat()
Declare Sub Checkfat
Declare Sub Clearbuffer

Declare Sub Gpsinit
Declare Sub Query
Declare Sub Sendmsg
'Set Mmcpower


call mmcinit
do

'Here put all the commands for mmc.

loop


'======= SUB ROUTINES AND FUNCTIONS for MMC=======
'____________________________________________________________________
Sub Cardformat()
#if Debug = 1
Print #1 , "Formatting"
#endif

'mark the start sector
' Input #1 , "Start" , Adr
Adr = &H0000
Comm = &H40 + 35
Sendcmd
Aresp = 00
Getresp
#if Debug = 1
If Aresp <> Rbyte Then
Print #1 , "ADD1 error"
End If

#endif
'mark the end sector
' Input #1 , "end" , Adr
Adr = 15360000
'THIS IS 30,000 SECTORS AND 29,999 RECORDS.

Comm = &H40 + 36
Sendcmd
Getresp
#if Debug = 1
If Aresp <> Rbyte Then
Print #1 , "ADD2 error"
End If
#endif
'erase

Comm = &H40 + 38
Sendcmd
Getresp



If Aresp <> Rbyte Then
#if Debug = 1
Print #1 , "Format Failed"
#endif
Cls
Lcd "Format Error"
Lowerline
Lcd "Send for Repair"
Do
Loop


End If

'Busy check
#if Debug = 1
Print #1 , "Busy check"
#endif
Readbyte
While Rbyte = 0
Readbyte
Wend
#if Debug = 1
Print #1 , "free"
#endif
'Now formatting is done. write the signature in 0th sector

Div = "TOTAL SOLUTIONS."
Adr = 0
Writesector

'Format done

End Sub
'____________________________________________________________________
Sub Getresp()
Responsewait:
Readbyte
' for DEBUG
#if Debug = 1
Print #1 , "RES IS " ; Hex(rbyte) ; "," ; 'DEBUG
#endif

For I = 1 To 255
If Rbyte = Aresp Then
Goto Responsedone
End If
Readbyte
#if Debug = 1
Print #1 , Hex(rbyte) ; "," ; 'DEBUG
#endif

Next I

Responseerror:
#if Debug = 1
Print #1 , "Error in resp"
#endif
Responsedone:
End Sub


'____________________________________________________________________
Sub Spiwait()
Spiwait1:
'#if Debug = 1
' Print #1 , "W"
'#endif
sbis spsr,7
rjmp spiWAIT1
Dbyte = Spdr
End Sub

'____________________________________________________________________
Sub Sendbyte()
Spdr = Spichar
'#if Debug = 1
' Print #1 , "S"
'#endif
Spiwait
End Sub

'____________________________________________________________________
Sub Sendcmd()
Set Cs
Spichar = &HFF
Sendbyte
Reset Cs

'COMMAND
'COMMAND
Spichar = Command(1)
Sendbyte
Spichar = Command(5)
Sendbyte
Spichar = Command(4)
Sendbyte
Spichar = Command(3)
Sendbyte
Spichar = Command(2)
Sendbyte
Spichar = Command(6)
Sendbyte

End Sub


'____________________________________________________________________
Sub Readbyte()
Spichar = &HFF
'#if Debug = 1
' Print #1 , "R"
'#endif
Sendbyte
Rbyte = Spdr
End Sub


'____________________________________________________________________
Sub Readsector
'cmd17
Comm = &H40 + 17
Sendcmd
Aresp = &H00
Getresp


If Rbyte <> Aresp Then
#if Debug = 1
Print #1 , "error in read command"
#endif
Goto Readerror

End If


Aresp = &HFE

Getresp

If Rbyte <> Aresp Then
#if Debug = 1
Print #1 , "error in read command"
#endif
Goto Readerror
End If

' K = 0
For K = 1 To 212
Readbyte
Indat(k) = Rbyte
Next K

For K = 213 To 512
Readbyte
Next

' Print
Exit Sub
Readerror:
Cls
Lcd "READ PROBLEM"
Lowerline
Lcd "Send for Repair"
Do
Loop


End Sub

'____________________________________________________________________
Sub Writesector()
Comm = &H40 + 24

Sendcmd
Aresp = &H00
Getresp


If Aresp <> Rbyte Then
#if Debug = 1
Print #1 , "write command not accepted"
#endif
Goto Writeerror
End If
'now send fe
Reset Cs
Spichar = &HFE
Sendbyte

For K = 1 To 212
Spichar = Indat(k)
Sendbyte
Next K
For K = 213 To 512
Spichar = &HFF
Sendbyte
Next K

Spichar = &HFF
Sendbyte
Sendbyte
Readbyte
' Print
Dbyte = Rbyte And &H0F

#if Debug = 1
Print #1 , "the responce of write is Rbyte=" ; Bin(rbyte)
Print #1 , "Dbyte=" ; Bin(dbyte)
#endif


If Dbyte <> &H05 Then
#if Debug = 1
Print #1 , "write is unsuccessful"
#endif
Goto Writeerror
End If

Exit Sub
Writeerror:
'The problem is in writing! dont accept any more records.
Cls
Lcd "SAVE PROBLEM"
Lowerline
Lcd "Send for Repair"
Do
Loop

End Sub
'____________________________________________________________________
Sub Mmcinit()

#if Debug = 1
Print #1 , "initializing MMC"
#endif



Mmcinitdone = 0
Cmda = 0 : Cmdb = 0
Set Cs
'Spichar = &HFF
For I = 1 To 100
Readbyte
Next I
Reset Cs

'cmd0
Comm = &H40
Adr = &H00000000
Trail = &H95

'COMMAND
Spichar = Command(1)
Sendbyte
Spichar = Command(5)
Sendbyte
Spichar = Command(4)
Sendbyte
Spichar = Command(3)
Sendbyte
Spichar = Command(2)
Sendbyte
Spichar = Command(6)
Sendbyte


Aresp = &H01
Getresp

If Rbyte = Aresp Then
Cmda = 1
#if Debug = 1
Print #1 , "init error in cmd0 resp is" ; Hex(rbyte)
#endif
End If
#if Debug = 1
Print #1 , "done cmd0, resp is " ; Hex(rbyte)
#endif
'cmd1
For K = 1 To 255
Comm = &H41
Trail = &HFF
Sendcmd
Aresp = &H00
Getresp
If Rbyte = Aresp Then
Cmdb = 1
Goto Cmd1done:
End If
Next K
#if Debug = 1
Print #1 , "error in cmd1 resp=" ; Hex(rbyte)
#endif
Cmd1done:
'Print "done cmd1, resp is " ; Hex(rbyte)
' Print "cmda=" ; Cmda
' Print "cmdb=" ; Cmdb

Mmcinitdone = Cmda And Cmdb
#if Debug = 1
Print #1 , "mmcinitdone=" ; Mmcinitdone
#endif
End Sub
 

proteus multimedia card image file

Hello, how do you simulate mmc in proteus?, because when i try, it is necesary to select an multimedia card image file, where can i get this file?
 

mmc and proteus

i used this and works ok.
i wrotes in winavr.

#ifndef __MOS_MMC__
#define __MOS_MMC__
//===================================
#define GO_IDLE_STATE 0
#define SEND_OP_COND 1
#define SEND_CSD 9
#define SEND_CID 10
#define SEND_STATUS 13
#define SET_BLOCKLEN 16
#define READ_SINGLE_BLOCK 17
#define READ_MULTIPLE_BLOCK 18
#define SET_BLOCK_COUNT 23
#define WRITE_SINGLE_BLOCK 24
#define WRITE_MULTIPLE_BLOCK 25
#define PROGRAM_CSD 27
#define SET_WRITE_PROT 28
#define CLR_WRITE_PROT 29
#define SEND_WRITE_PROT 30
#define TAG_ERASE_GROUP_START 31
#define TAG_ERASE_GROUP_END 36
#define ERASE 38
#define LOCK/UNLOCK 42
#define READ_OCR 58
#define CRC_ON_OFF 59


#define SPIDI PINB.6 // Port B bit 6 (pin7): data in (data from MMC)
#define SPIDO PORTB.5 // Port B bit 5 (pin6): data out (data to MMC)
#define SPICLK PORTB.7 // Port B bit 7 (pin8): clock
#define SPICS PORTB.4 // Port B bit 4 (pin5: chip select for MMC
#define true 1
#define false 0
#include "delay.h"

char writeSector(long int sector);
char readSector(long int sector);
//==================================
#define sectorSize 512
char sector[sectorSize];
bit mmc_inited = false;
//==================================
char SPI(char d) {
SPDR = d;
while(!(SPSR & (0x80)));
return SPDR;
}

char Command(char befF, int AdrH, int AdrL)
{
char t;
int i;
// sends a command to the MMC
SPI(0x40 | befF);
SPI(AdrH >> 8);
SPI(AdrH);
SPI(AdrL >> 8);
SPI(AdrL);
SPI(0x95);//just valid for idle state command
for (i = 0; i < 2000 && (t = SPI(0xFF)) == 0xff ; i++);
return t;
}
//============
char mmc_init()
{
int i, t;
SPICS = false;
mmc_inited = false;

SPICS = true; // disable MMC
// start MMC in SPI mode
for (i = 0; i < 200; i++)
SPI(0xFF); // send 20*8=160 clock pulses
SPICS = false; // enable MMC

if (Command(GO_IDLE_STATE, 0, 0) != 1)
return t|0x80;

// if there is no MMC, prg. loops here
for (i = 0; i < 100 && (t = Command(SEND_OP_COND, 0, 0) != 0); i++);
if(i >= 100)
return t|0x80;

//crc off
if (Command(CRC_ON_OFF, 0, 0) != 0)
return t|0x80;

//set block lenght
if(Command(SET_BLOCKLEN, 0, sectorSize) != 0)
return t|0x80;

mmc_inited = true;
SPICS = true;
return 0;
}

char readSector(long int sectorNum)
{
int i;
char t;
SPICS = false;
//send command
if ((t = Command(READ_SINGLE_BLOCK, sectorNum>>7, sectorNum << 9)) != 0)
{
SPICS = true;
return t;
}
//wait for start byte : 0xfe
for (i = 1; i < 2500 && SPI(0xff) != 0xfe; i++)
if (i == 2500)
{
SPICS = true;
return 0x80;
}
//read data
for (i = 0; i < sectorSize; i++)
sector = SPI(0xff);
//read 16bit crc
SPI(0xff);
SPI(0xff);

SPICS = true;
return 0;
}

char writeSector(long int sectorNum)
{
int i;
SPICS = false;
for (i = 0; i < 250 && (Command(WRITE_SINGLE_BLOCK, sectorNum>>7, sectorNum << 9) != 0); i++);
if( i == 250 )
{
SPICS = true;
return 1;
}

//wait to mmc become ready
for (i = 0; i < 10; i++)
SPI(0xFF);
//begin write
SPI(0xFE);
//sending data
for (i = 0; i < sectorSize; i++)
SPI(sector);
// at the end, send 16bit crc
SPI(0xFF);
SPI(0xFF);
//get and check response
if ((SPI(0xFF) & 0x1f) != 0x05)
{
for (i = 0; i < 250 && ((SPI(0xFF) & 0x1f) != 0x05); i++)
if (i == 250)
{
SPICS = true;
return 2;
}
}
// wait until MMC is not busy anymore
if (SPI(0xFF) == 0xff)
{
for (i = 0; i < 255 && (SPI(0xFF) == 0xff); i++) ;
if (i == 255)
{
SPICS = true;
return 3;
}
}

SPICS = true;
return 0;
}
//====
#endif
 
bascom nofat

asit said:
I have got a few requests for the BASCOM Code for interfacing MMC to AVR. So, I am posting it here.


Is it responsible for every avr micro?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top