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.

SD card read returns 0x01 error token after reading 6 bytes sucsessfully.

Status
Not open for further replies.

drbizzarow

Advanced Member level 1
Joined
May 24, 2006
Messages
414
Helped
25
Reputation
50
Reaction score
15
Trophy points
1,298
Activity points
3,662
hi,
i am trying to interface SD card (not in fat format on read write bytes).I have successfully interface 1GB SD card read and write option both my code work properly.
But when i try my same code with 2GB SD card i can write my data on it successfully (i have checked through HxD softwear) but when i am read it back...... after reading 6 byte correctly, SD card return "0x01 error token" and then start returning 0xff.

can any body knows why its happening.
Thanks in advance.
 
Last edited:

can you please help me proving me the code for interfacing 1GB SD card ,i need it for my final year project
 

i am not using fat i am simply saving bytes. i am using 89c51ed2 controller is this ok to you ?
 

Hello!

It's very difficult to reply because nobody can guess what 0x01 return code means.
You should dig into the code and try to figure out.

For Gewali: sd card source code exists on the net. Try to enter "sd source code" in your favorite
search engine. You can probably even find the code that fits the processor you are using.

Dora.
 

hii,
i am keep digging and digging .......
according to specifications error code 0x01 means unknown error. i dont know why my code running perfect on 1gb sd card... i have try to different 1GB SD card and my code is working ok on both of these.
but not on 2GB.

- - - Updated - - -

here is my code.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
#include "reg_c51.h"
#include <intrins.h>
#include <stdio.h>
#include <string.h>
//////////////////////////////////
//  PIN ASSINGMENTS              //      
//////////////////////////////////
 
//-------General Peraphirals
sbit SYS_LED   = P0^4;
sbit MMC_SPIN  = P1^2;
//-----MACROS
#define     HIGH            1
#define     LOW                0
#define     SYS_LED_ON         SYS_LED = LOW;
#define     SYS_LED_OFF         SYS_LED = HIGH;
 
#define    SERIAL_PACKET_SIZE       20
#define    BUFERS_SIZE            SERIAL_PACKET_SIZE - 2
#define    TIMER0_RELOAD_VALUE    -0x2e    //for 50ms time interval
 
#define     MMC_SEL    MMC_SPIN = 0;
#define     MMC_DSEL   MMC_SPIN = 1;
 
xdata char sector[512];
 
void serialTx(unsigned char chr);
//////////////////////////////////////////////
//       GLOBAL VERIABLES DECLERATIONS      //      
//////////////////////////////////////////////
char SpiRcvDat;
char data_example=0x55;
char data_save;
bit transmit_completed= 0;
char x, rs232byt;
/*----------------------------------Interrupts--------------------------------------*/
 
void serial_interrupt(void) interrupt 4 using 2 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~SERIAL ISR*/
{
    if (RI)
   {
      rs232byt =  SBUF;
      RI = 0;
   } 
}
 
/*------------------------------------------------------------------------------------*/
/*-------------------------------------UDF--------------------------------------------*/
/*------------------------------------------------------------------------------------*/
void delay(unsigned int times)
{
   unsigned char i;
   while(times-- > 0)
   {
      i = 255;
      while(i-- > 0)
      {
        i = i;
      }
   }
}
 
/******************************************SPI Functions********************************/
void serialTx(unsigned char chr) 
{
   SBUF= chr;
   while (!TI);
   TI= 0;
}
 
char SpiTx(unsigned char txbyte) 
{ 
   SPDAT=txbyte;        /* send data */
   while(!(SPSTA & 0x80));/* wait end of transmition */
   //serialTx(SPDAT);
   return SPDAT;
}
 
void uart_puts (char *s) {
    //  loop until *s != NULL
    while (*s) {
        serialTx(*s);
        s++;
    }
}
char Command(char befF, unsigned long  Adr, char befH )
{   // sends a command to the MMC.
    _nop_();_nop_();
    SpiTx(0xFF);
    SpiTx(befF);
    SpiTx((char)(Adr >> 24));
    SpiTx((char)(Adr >> 16));
    SpiTx((char)(Adr >> 8));
    SpiTx((char)(Adr >> 0));
    SpiTx(befH);
    SpiTx(0xFF);
    return SpiTx(0xFF); // return the last received character
    _nop_();_nop_();
}
 
int MMC_Init(void) { // init SPI
    char i;
    MMC_DSEL
    for(i=0; i < 10; i++) SpiTx(0xFF); // send 10*8=80 clock pulses
 
    MMC_SEL //PORTB &= ~(1 << SPICS); // enable MMC
    while (Command(0x40,0x00000000,0x95) != 0x01) {serialTx('_');};// goto mmcerror; // reset MMC
 
    MMC_DSEL
    SpiTx(0xFF);
    MMC_SEL
st: // if there is no MMC, prg. loops here
    if (Command(0x41,0x00000000,0xFF) !=0x00) 
    {
            serialTx('x'); 
            goto st;
    }
    serialTx('1');
    MMC_DSEL
 
    MMC_SEL
    Command(0x50, 0x00000400, 0xFF);
    MMC_DSEL
 
    return 1;
mmcerror:
    serialTx('0');
    MMC_DSEL
    return 0;
}
 
void fillram(void)   { // fill RAM sector with ASCII characters
    int i,c;
    char mystring[18] = "Hello World..... ";
    c = 0;
    for (i=0;i<=512;i++) {
        sector[i] = mystring[c];
        c++;
        if (c > 17) { c = 0; }
    }
}
 
int writeramtommc(unsigned long sectoradd) { // write RAM sector to MMC
    int i, retry=0;
    char c;
    MMC_SEL
    // 512 byte-write-mode
    if (Command(0x58,sectoradd,0xFF) !=0) {
        serialTx('e');//uart_puts("MMC: write error 1 ");
        return 1;   
    }
    //SpiTx(0xFF);
    SpiTx(0xFF);
    SpiTx(0xFE);
    // write ram sectors to MMC
    for (i=0;i<512;i++) {
        SpiTx(sector[i]);
         //delay(300);
    }
    // at the end, send 2 dummy bytes
    SpiTx(0xFF);
    SpiTx(0xFF);
 
    c = SpiTx(0xFF);
    c &= 0x1F;  // 0x1F = 0b.0001.1111;
    serialTx('+');
    serialTx(c);
    if (c != 0x05) { // 0x05 = 0b.0000.0101
        uart_puts("w");uart_puts("e");//uart_puts("MMC: write error 2 ");
        MMC_DSEL
        return 1;
    }
    // wait until MMC is not busy anymore
    while(SpiTx(0xFF) != (char)0xFF);
 
//  MMC_DSEL
//  SpiTx(0xff);   //just spend 8 clock cycle delay before reasserting the CS line
//  MMC_SEL         //re-asserting the CS line to verify if card is still busy
 //   while(!   SpiTx(0x00)) //wait for SD card to complete writing and get idle
 //   if(retry++ > 0xfffe){MMC_DSEL; return 1;}
//      MMC_DSEL
    
    serialTx('+');
    MMC_DSEL
    return 0;
}
 
 
int sendmmc(unsigned long sectoradd) { // send 512 bytes from the MMC via the serial port
    int i, ix, j;
    unsigned char r1 = 0;
serialTx('=');
 
    MMC_SEL
    r1 =  Command(0x51,sectoradd,0xFF);
    serialTx(r1);
    for (ix = 0; ix < 50000; ix++) {
        if (r1 == 0x00) break;
        r1 =  Command(0x51,sectoradd,0xFF);
        r1 = SpiTx(0xFF);
    }
    
    if (r1 != 0x00) {
        serialTx('R');serialTx('e');//uart_puts("MMC: read error 1 ");
        return 1;
    }
 
    // wait for 0xFE - start of any transmission
    // ATT: typecast (char)0xFE is a must!
    MMC_DSEL
    MMC_SEL
    r1 = SpiTx(0xff); 
    while(r1 != (char)0xFE){r1 = SpiTx(0x00); serialTx('|'); serialTx(r1); serialTx('|');}
    serialTx('(');
    for(i=0; i < 512; i++) {
        //serialTx(SpiTx(0xFF));
        j = SpiTx(0x00);
        serialTx(j);
    }
    // at the end, send 2 dummy bytes
    SpiTx(0xFF); // actually this returns the CRC/checksum byte
    SpiTx(0xFF);
 serialTx(')');
    MMC_DSEL
    return 0;
}
 
 
int main(void) 
{
    unsigned long addx;
        /*--------Bismillah-------*/
 
      /* setup Serial interrupt */
   TMOD  = TMOD | 0x20;    //TIMER1 IN MOD2 (AUTO RELOAD)
   TH1   = -3;             //BAUD RATE = 9600bps @ 11.0592MHz
   TR1   = 1;            //RUN TIMER1 FOR SERIAL CLOCK
   SCON  = 0x52;         //8BIT, 1STOPBIT, NO PARITY
   RI    = 0;
   TI    = 0;            
   ES      = 1;            //ENABLE SERIAL INT
        /* setup timer 0 interrupt */
//   TR0 = 0;
//   TH0 = 0X4B;
//   TL0 = 0xFD;              //  set timer period           
//    TMOD = TMOD | 0x01;      //  select mode 1               
//    TR0 = 1;                 //  start timer 0                                            
      /* Ext0 interrupt Settings */
   //IT1 = 1;             //ext0 neg edge trigger
      /*SPI Settings And Interrupt */
   SPCON = 0x00;
   SPCON = 0x10;                 /* Master mode */
   MMC_DSEL                      /* Disable slave */
   SPCON |= 0x01;                /* Fclk Periph/64 */
   SPCON |= 0x80;                /* Fclk Periph/64 */
   //SPCON |= 0x04;                /* CPHA=1; transmit mode example */
   //SPCON |= 0x08;                /* CPOL=1; transmit mode example */
   //IEN1 |= 0x04;                 /* enable spi interrupt */
   SPCON |= 0x40;                /* run spi */
   EA=1;                         /* enable interrupts */
   P0 = 0xff;
 
   SYS_LED = 1;
   delay(500);
   MMC_Init();
   fillram();
   addx = 0x00000200;
   writeramtommc(addx);
   delay(200);
   sendmmc(addx);
   delay(200);
   sendmmc(addx + 0x00000200);
   while(1)                     /* endless  */
   {  
      //addx += 0x00000400;
      SYS_LED = ~SYS_LED;
      delay(100);
  }
}

 
Last edited by a moderator:

Hello!

Well, from my experience, 1 or 2 GB should indeed be the same. It changes slightly for 4 GB
for the SD driver itself, and also for FAT.
I wrote my driver starting from the specs. What helped me most is the bloc diagram
explaining the SD initialisation.

Dora.
 
Last edited:

can you once confirm that both the cards are from same manufacture
and are of same specifications ( different cards may have different voltage requirements or different delays )
 

both capacity is different one is 1GB another is 2GB.
even problem 2GB card also initializes OK, write 512 bytes OK but when i read those written bytes i can only read 6 bytes OK and after that my 2gb card return 0x01 error token and after that it start return 0xff.......
 

Thank you Dora ,I'll try it
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top