Grzegorz Latocha
Guest
Thu Feb 21, 2008 7:55 am
Witam!
Chciałbym ( a właściwie to muszę ) odczytać i zapisywać kartę SD w moim
układzie. Karta jest podłączona do PIC18LF4550 chodzącego na 3,3V do
portu SPI. na liniach portu są pull-upy 1k. do tego oczywiście linia CS.
Karta to Panasonic 16MB
Korzystałem z kilku różnych przykładów, chodzi mi o cokolwiek, żeby to
zrozumieć, a potem wykorzystywać. inicjacja wygląda u mnie tak:
1. Wysyłam 80 cykli zegarowych
2. wysyłąm CMD0 R1=0x01
3. wysyłam CMD1 R1=0x00
4. wysyłam CMD55
5. wysyłam ACMD41 R1=0x00
6. wysyłam CMD16 z parametrem 8 R1=0x00 //i tu powinna być karta
zainicjowana (wygląda na to że jest) przy parametrze 512 (wyskakuje
Parameter Error).
Następnie próbuję coś odczytać, ale z pamięci to ni jak ma się do tego
co powinno tam być, większość zera + jakieś śmieci. Jak czytam rejestr
CID to wychodzi 0x01 (może to jest kod Matsushity, ale nie udało mi się
tego znaleźć) potem PASO i dalej śmieci. Ale co dziwne, cokolwiek bym
nie próbował odczytać, to co 8 bajt dostaję 0x04 (co wygląda jak error
Illegal Command). Mam nadzieję, że ktoś mi coś poradzi. Wklejam
oczywiście kod:
pozdrawiam
Grzegorz Latocha
P.S. sorry za długość posta
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
OpenSPI(SPI_FOSC_64, MODE_11, SMPMID); //otwieram port na wolnej prędkości
DelayMS(100); //odczekuję, aż karta się uruchomi
SD_CE = 1;
for (timeout=0; timeout<10; timeout++)
WriteSPI(0xFF); //wysyłam 10 razy 8 cykli - tego wymaga karta
SD_CE = 0;
DelayMS(10); //włączam SPI w karcie
//Wysyłanie CMD0
do
{
odpowiedz = SDSendCMD(0x00,0x00000000,0x95);
} while(odpowiedz != 0x01);
EEPROMWrite(0x00,odpowiedz); //nie ma wyświetlacza, więc tak sprawdzam
co przyszło
LED1=0;
//wysyłanie CMD1 tak długo, aż karta się uruchomi
do
{
SD_CE = 1;
WriteSPI(0xFF);
SD_CE = 0;
odpowiedz = SDSendCMD(0x01,0x00000000,0xFF);
}while((odpowiedz & 0x01)!=0);
EEPROMWrite(0x01,odpowiedz);
LED2=0;
WriteSPI(0xff);
SD_CE = 0;
odpowiedz = SDSendCMD(55,0x00000000,0xFF); //przed komendą ACMD41
WriteSPI(0xFF);
LED3=0;
do
{
odpowiedz = SDSendCMD(41,0x00000000,0xFF);
} while((odpowiedz & 0x01) !=0);
EEPROMWrite(0x02,odpowiedz);
WriteSPI(0xFF);
odpowiedz=SDSendCMD(16,8,0xff); //ustawiam rozmiar bloku na 8B
EEPROMWrite(0x03,odpowiedz);
WriteSPI(0xFF);
//odczyt karty chcę odczytać 8 bajtow z adresu 0
ReadData();
LED4 = 0;
DelayMS(1000);
LED4 = 1;
//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
void ReadData(void)
{
SD_CE = 0;
if(SDSendCMD(17,0,0xFF)==0x00) LED3=0;
//czekanie na początek danych
do
{
odpowiedz = ReadSPI();
} while(odpowiedz!=0xFE); //czekanie na tokena
EEPROMWrite(0x12,odpowiedz);
LED4=0;
for(Temp=0;Temp<8;Temp++)
SD_Buffer[Temp] = ReadSPI(); //czytanie danych
ReadSPI(); //czytanie crc
ReadSPI();
WriteSPI(0xFF); //wysyłam clock
SD_CE = 1;
for(Temp=0;Temp<8;Temp++)
EEPROMWrite(0x20+Temp,SD_Buffer[Temp]);
SD_CE = 1;
}
Xaveri
Guest
Thu Feb 21, 2008 3:49 pm
Nie jest czasem tak, że karty umożliwiają jedynie zapis / odczyt całych 512
bajtowych bloków? Mniej nie odczytasz / zapiszesz - musisz mieć procka z
buforem w ram 512 bajtów...
Grzegorz Latocha
Guest
Fri Feb 22, 2008 9:59 am
Xaveri pisze:
Quote:
Nie jest czasem tak, że karty umożliwiają jedynie zapis / odczyt całych
512 bajtowych bloków? Mniej nie odczytasz / zapiszesz - musisz mieć
procka z buforem w ram 512 bajtów...
Teoretycznie nie, ale komenda ustawienie bloku na 512B wywala mi błąd
Illegal Prarameter. A jak odczytywałem całe 512bajtów, to początek był
identyczny jak przy 8, a potem co 8 bajt to 04 tak jak pytałem.
Zamówiłem kartę MMC, podobno robi mniej problemów na początek