SD kart sektör içeriğini yanlış okuyor

Başlatan WrtM, 22 Nisan 2016, 23:17:27

WrtM

sd kart kullanarak yaptığım bir projede sorun yaşıyorum ,sd kart başlangıç ayarlarını yaptım sd kartın geri gönderdiği veriler doğru(cmd0,cmd8,cmd58,acmd41,acmd16 vb. komutlar için) ancak iş sektör okumaya gelince hatalar meydana geliyor,veri okumak için cmd17 komutu kullanıyorum kartın hazır olduğunu belirttiği 0x00 ve 0xfe verilerini karttan okuyorum ve cmd 16 komutu ile belirttiğim kadar 0xff gönderip data okuyorum ama okuduğum datalar sd karttta bulunan datalardan farklı misal 1. sektörü okumak istiyorum gelen datalar 0x00 içerikli arada acayip başka değerler var .winhex gibi bir programdan sd kartın içeriğine baktığımda ise 1. sektörün içerisinde b0,b1 gibi başlangıç dataları olduğunu görüyorum. sorunun cmd17 komutunda olduğunu düşünüyorum siz be dersiniz?
cmd17 kısmı;
CS=0;
SPI_SendByte(0X51);

SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X02);
SPI_SendByte(0X00);
unsigned  h=3000;
while(h--);
for(retur=SPI_ReadByte(0xFF),k=0;retur!=0x00;retur=SPI_ReadByte(0xFF)); //00 gelene kadar 0xff yolla
for(retur=SPI_ReadByte(0xFF),k=0;retur!=0xfe;retur=SPI_ReadByte(0xFF)); //fe gelene kadar 0xff yolla
SPI_SendByte(0Xff);
SPI_SendByte(0Xff);
h=3000;
while(h--);
for(unsigned int h=512;h!=0;h--)
SendByte(SPI_ReadByte(0xFF));
CS=1;
SPI_SendByte(0Xff);



kodların hepsi;
#include <iostm8s003k3.h>

#define CS PC_ODR_ODR4

void InitUART(void)
{
  UART1_BRR2  = 0x00;
  UART1_BRR1  = 0x0d;
  UART1_CR2_REN  = 1;
  UART1_CR2_TEN  = 1;
}
 
void SendByte(char i)
{
  while(UART1_SR_TXE!=1);
  UART1_DR = i;
}
 
void SendString(const char *s)
{
   while(*s)
      SendByte(*s++);
}

void InitSPI(void)
{ 
    
  SPI_CR1_LSBFIRST = 0;   //MSB is transmitted First
  SPI_CR1_BR= 3;         //SPI_Baudrate = fmaster/16 125kHZ
  SPI_CR1_CPOL = 0;       //SCK to 0 when idle
  SPI_CR1_CPHA = 0;       //The first transition is the first data capture edge
  SPI_CR2_BDM = 0;        //line Unidirectional data mode selected
  SPI_CR2_RXONLY = 0;     //Full Duplex  
  SPI_CR1_MSTR = 1;       //Master Configuration

 
  SPI_CR2_SSI=1;
  SPI_CR2_SSM=1;
  SPI_CR1_SPE=1;       //Master Configuration
  
  PC_DDR_DDR4=1;  //CS PİNİ
  PC_CR1_C14=1;
}
void SPI_SendByte(char i)
{
 
   SPI_DR = i;             // SPI Data register ına veriyi yaz 
   while(!SPI_SR_TXE);     // TX Buffer boşalana kadar bekle
   SPI_SR_TXE = 0;         // Bayrağı temizle
   while(SPI_SR_BSY);      // SPI meşgul ise bekle
}
unsigned char SPI_ReadByte(char send_data)
{
  PC_ODR_ODR4=0;
   unsigned char data=0;
   //SPI_CR1_SPE=1;           //SPI Enable
   SPI_DR =send_data;
   while(!SPI_SR_TXE);     // TX Buffer boşalana kadar bekle
   SPI_SR_TXE = 0;         // Bayrağı temizle
   // SPI_DR =0x55;
   while(!SPI_SR_RXNE);
   SPI_SR_TXE = 0;
   data=SPI_DR;
    while(SPI_SR_BSY);      // SPI meşgul ise bekle
  //SPI_CR1_SPE=0;
    PC_ODR_ODR4=1;
   return(data);

}

void SD_read(unsigned long sector) {
    unsigned short i, pos = 0;
    
    CS=0;
    SPI_SendByte(0x51);
    SPI_SendByte(sector>>15); // sector*512 >> 24
    SPI_SendByte(sector>>7);  // sector*512 >> 16
    SPI_SendByte(sector<<1);  // sector*512 >> 8
    SPI_SendByte(0);          // sector*512
    SPI_SendByte(0xFF);
    
    for(i=0; i<10 && SPI_ReadByte(0xFF) != 0x00; i++) {} // wait for 0
    
    for(i=0; i<10 && SPI_ReadByte(0xFF) != 0xFE; i++) {} // wait for data start
    
        
    for(i=0; i<512; i++) // read len bytes
        SendByte(SPI_ReadByte(0xFF));       
        
    // skip checksum
    SPI_SendByte(0xFF);
    SPI_SendByte(0xFF);    

    CS=1;   
    for(;;);
}
int main (void)
{    InitSPI();
     InitUART();  
     SendString("BASLA");
    
     //pd0 çıkış yap 
     PD_DDR_DDR0=1;
     PD_CR1_C10=1;
     PD_ODR_ODR0=1; //LEDİ SÖNDÜR

for(;;)
{
  unsigned char k;
  unsigned char retur;
CS=1;
 for(k=10;k!=0;k--)
 {
 SPI_SendByte(0XFF);
 }
CS=0;
SPI_SendByte(0X40);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X95);
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff&&k<10;k++,retur=SPI_ReadByte(0xFF));  //karşı taraftan oxff cevabı dışında veri gelene kadar 0xff yolla istenilen cevap gelmese bile 10 kere yap
if(retur==0x01)PD_ODR_ODR0=0;
CS=1;


//cmd8
SendString("CMD8");
CS=0;
SPI_SendByte(0X48);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X01);
SPI_SendByte(0XAA);
SPI_SendByte(0X87);
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff&&k<10;k++,retur=SPI_ReadByte(0xFF));
SendByte(retur);
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff&&k<10;k++,retur=SPI_ReadByte(0xFF));
SendByte(retur);
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff&&k<10;k++,retur=SPI_ReadByte(0xFF));
SendByte(retur);
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff&&k<10;k++,retur=SPI_ReadByte(0xFF));
SendByte(retur);
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff&&k<10;k++,retur=SPI_ReadByte(0xFF));
SendByte(retur);
CS=1;

for(unsigned char t=0;t<50;t++)
{
unsigned h=3000;
while(h--);
//ACMD41
SendByte(0x55);
CS=0;
SPI_SendByte(0XFF);
SPI_SendByte(0X77);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0XFF);
SPI_SendByte(0XFF);
SPI_SendByte(0XFF);
CS=1;
//for(retur=SPI_ReadByte(0xFF),k=0;retur!=0x01&&k<100;k++,retur=SPI_ReadByte(0xFF));
SPI_SendByte(0XFF);
CS=0;
 h=3000;
while(h--);
SPI_SendByte(0Xff);
SPI_SendByte(0X69);
SPI_SendByte(0X40);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0XFF);
for(retur=SPI_ReadByte(0xFF),k=0;retur!=0x00&&k<50;k++,retur=SPI_ReadByte(0xFF));
CS=1;
SPI_SendByte(0XFF);
}


//CMD58

CS=0;
SPI_SendByte(0X7A);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X01);

for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff;retur=SPI_ReadByte(0xFF));
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff;retur=SPI_ReadByte(0xFF));
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff;retur=SPI_ReadByte(0xFF));
for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff;retur=SPI_ReadByte(0xFF));
//for(retur=SPI_ReadByte(0xFF),k=0;retur==0xff;retur=SPI_ReadByte(0xFF));
CS=1;
SPI_SendByte(0XFF); 

SPI_CR1_BR= 0; 
//CMD16
SendByte('A');
CS=0;
SPI_SendByte(0Xff);
SPI_SendByte(0X50);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X02);
SPI_SendByte(0X00);
for(retur=SPI_ReadByte(0xFF),k=0;retur!=0x00;retur=SPI_ReadByte(0xFF));
CS=1;
SPI_SendByte(0Xff);

//SD_read(1);

//CMD17
CS=0;
SPI_SendByte(0X51);

SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
unsigned  h=3000;
while(h--);
for(retur=SPI_ReadByte(0xFF),k=0;retur!=0x00;retur=SPI_ReadByte(0xFF)); //00 gelene kadar 0xff yolla
for(retur=SPI_ReadByte(0xFF),k=0;retur!=0xfe;retur=SPI_ReadByte(0xFF)); //fe gelene kadar 0xff yolla
SPI_SendByte(0Xff);
SPI_SendByte(0Xff);
h=3000;
while(h--);
for(unsigned int h=512;h!=0;h--)
SendByte(SPI_ReadByte(0xFF));
CS=1;
SPI_SendByte(0Xff);
for(;;);

}
    
}

RaMu

Okumak istediğin sektör + 0x2000  i oku,

yani
cmd_oku , arguman, crc
32 bit sektör adresi olan okuma komutu argumanı kullanıyoruz,
burada sektör 0 ı okumak istiyorsan,
argüman 0x00 0x00 0x00 0x00  değil,
argüman 0x00 0x00 0x20 0x00 olarak gönderilecek
misal
SECTOR 0x01E0 i okumak için;
0x51,0x00,0x00,0x21,0xE0,0x00  gönderilecek
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

WrtM

1. sektörü okumak için ;

SPI_SendByte(0X51);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X02);
SPI_SendByte(0X01);   gönerdim ancak 0x00 ve 0xfe cevap olarak gelmedi dolayısıyla okuyamadım.



SPI_SendByte(0X51);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X20);
SPI_SendByte(0X00);    0. sektörü okumak için dediğiniz gibi bu komutu gönderdim okuduğum değerlerin hepsi 00 ancak winhexde baktığımda 0.sektörde değişik değerler olduğunu görüyorum.



SPI_SendByte(0X51);
SPI_SendByte(0X00);
SPI_SendByte(0X00);
SPI_SendByte(0X20);
SPI_SendByte(0X01);   gönderdim yine netice alamadım.


bunun haricinde parametre verilerinin hepsini 0x00 gönderip gelen verileri seri port programında ascii olarak gördüğümde sd kartın " invalid partition table"  "error loading operation system"  "missing operating system " gibi cümleler gönderdiğini gördüm bunlar ne demek acaba?


RaMu

#3
Denemelerini nerede yapıyorsun (simulasyon mu gerçek devre mi) önemli,
kesinlikle gerçek devrede denemeli ve
kesinlikle lojik analizör kullanarak spi hattını gözlemlemelisin.

Yoksa söyleyeceklerimiz havada kalır.

mesaj birleştirme:: 25 Nisan 2016, 07:56:28

Birde şimdi farkettim komutları aynen bu şekilde gönderiyorsan hatalı demektir,
komutlar her zaman 6 byte olmak zorunda,
SPI modda CRC kapalı bırakılsa dahi,
CRC byte ı gönderilmek zorunda,
ne gönderdiğin önemli değil ama göndermek zorundasın,
0x00 gönderiyorum ben.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

WrtM


RaMu

//ACMD41
SendByte(0x55);
Diye başlayan ACMD41 cmd 55 kısmı
0x77,0x00,0x00,0x00,0x00,0x65
şeklinde oloacak, yani CRC si yollanacak


h=3000;
while(h--);
SPI_SendByte(0Xff);
SPI_SendByte(0X69);
SPI_SendByte(0X40);

diye başlayan ACMD41 in CMD41 kısmı
0x69,0x40,0x00,0x00,0x00,0xE5
olacak, CRC yollanacak,

CMD58
0x7A,0x00,0x00,0x00,0x00,0xFD
olacak.


Daha çok fazla şey var,
bu anlat anlat bitmez,
ben iyi bilmeme rağmen çok fazla hata sonucu ancak çalıştırabildim,
çok çeşitli SD kartlar ve
bunlarında farklı init işlemleri var,
biraz uğraşacaksın,
sdcard association .org da sd kart datasheet leri var,
içlerinde boğulabilirsin ama faydası olur.

@z hocanın forumda paylaştığı bir konuda ve sitesinde sd kart anlatımı var.

birde benim test edip paylaştığım,
isis simulasyonları çalışan ve mevcut olan,
CcsC ve mikroC ile sd kart örnekleri var.

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

WrtM

of hocam of şu sd kart işleri çok sıkıntılı,kod doğru bile olsa sd kart versiyonları vs. nedenlerle çok sıkıntı çıkıyor.bu işe başladığımda ilk olarak elm-chan isimli vatandaşın kodlarını kullandım şu meşhur fatlı olanını ancak  bir neticeye varamadım.aynı şekilde daha sonra ccs c nin hazır kütüphanelerini kullanmayı denedim sonuç yine hüsran yine hüsran 2 kere sd kart değiştirdim biri 128 mb diğeri 256 mb ikisi içinde türkiyede bulamadığımdan çinden sipariş verip bayağı bir zaman bekledim.elimde 8 ve 16 gblık sd kart var onlarla hiç iletişim kuramıyorum internettede zaten yeterli örnek yok yüksek kapasite için bakalım biraz daha uğraşıyım olmazsa basiretimiz bağlanmış deyip çekilelim kenara.

RaMu

Yeterli sayıda örnek var,
Türkçe kaynak dahi var,
örnek yoksa dediğim gibi datasheet ler var.

128mb veya 256 mb gibi kartları okumak daha zor olabilir,
şuan bulacağın yakın zamandaki örnekler 2 gb 4 gb kartlarla daha iyi çalışır,
onlara uygun olma ihtimalleri daha yüksek.
Ben 2gb ~ 32gb sd kartlarla iletişim kurabildim.

Bir önceki mesajda belirttiğim örnekleri bulup incelemen fayda sağlar.
Benim paylaştığım sd kart örneği CcsC nin hazır kütüphanesi değil,
herhalde Suky adlı bir İspanyol olsa gerek onun kütüphanesi,
Açtığım konuda detayları ve kullanımı mevcut.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html