Witam, próbuję zrobić interfejs po SPI między mikrokontrolerem ARM (lpc2114) a kartą MMC. Skorzystałem z wiadomości zawartych w artykule ep 8/2004 ale pojawil sie problem. Otóż zgodnie ze standardem bajt poprzedzający wysyłanie i odczyt danych powinien mieć wartość 0xFE, jednak ja po inicjalizacji karty i odebraniu bajtu odpowiedzi 0x00 w przypadku karty Kingston MMC mobile moge odczytac cos z rejestru CID i CSD jeli Data Token = 0xFC!!! Podobnie gdy chce odczytać jakis sektor z karty. Poza tym po zapisie nigdy nie otrzymuję Data Response = 0x05, tylko po 0x00 jest zawsze 0xFF. Myślałem, że to może z kartą jest coś nie tak więc sprawdziłem na innej (niestety także Kingston) i jest dokładnie to samo. Program raczej jest napisany poprawnie, porównałem z różnymi aplikacjami i wszędzie jest obsługa zrealizowana niemal identycznie.
Proszę wszystkich znających się na tym temacie o jakąś odpowiedź. Dzięki i pozdrawiam
Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięWielki problem z kartami MMC Kingston
Moderatorzy:Jacek Bogusz, procesorowiec, Moderatorzy
Re: Wielki problem z kartami MMC Kingston
no jesli program jest dobrze napisany to możesz usiąść i płakać - nic innego nie pozostajeWitam, próbuję zrobić interfejs po SPI między mikrokontrolerem ARM (lpc2114) a kartą MMC. Skorzystałem z wiadomości zawartych w artykule ep 8/2004 ale pojawil sie problem. Otóż zgodnie ze standardem bajt poprzedzający wysyłanie i odczyt danych powinien mieć wartość 0xFE, jednak ja po inicjalizacji karty i odebraniu bajtu odpowiedzi 0x00 w przypadku karty Kingston MMC mobile moge odczytac cos z rejestru CID i CSD jeli Data Token = 0xFC!!! Podobnie gdy chce odczytać jakis sektor z karty. Poza tym po zapisie nigdy nie otrzymuję Data Response = 0x05, tylko po 0x00 jest zawsze 0xFF. Myślałem, że to może z kartą jest coś nie tak więc sprawdziłem na innej (niestety także Kingston) i jest dokładnie to samo. Program raczej jest napisany poprawnie,
A tak poważnie to zamieść procedury inicjalizacji karty , odczytu i zapisu danych. Dobrze gdybyś pokazał jak inicjujesz SPI w LPC2114. - nikt tu nie jest Duchem Swietym zeby telepatycznie stwierdzić jak to robisz.
Pocieszające:) ustawienia SPI i są standardowe:
void spi_init(void) // inicjalizacja interfejsu SPI
{
/* Configure Pin Connect Block */
PINSEL0 |= 0x5500;
/* Set pclk to same as cclk */
//VPBDIV=0x1;
/* Set to highest speed for SPI at 10 MHz- > 1.25 MHz */
S0SPCCR=248;
/* Device selected as master */
S0SPCR=0x30;
IODIR0 &=~(1<<5); //Setzen von Pin MMC_DI auf Input
IODIR0 |= (1<<4); //Setzen von Pin MMC_Clock auf Output
IODIR0 |= (1<<6); //Setzen von Pin MMC_DO auf Output
IODIR0 |= (1<<23); //Setzen von Pin MMC_Chip_Select auf Output
IODIR0 |= (1<<7);
}
inicjalizacja karty
u08 mmc_reset(void)
{
sbi(MMC_DDR, MMC_CS); // linia portu CS jako wyjście
sbi(MMC_PORT_DIS, MMC_CS); // CS wysoki
spi_init(); // inicjalizacja SPI
flush_mmc(10); //80pustychcyklizegarowych
// wysłanie komendy GO_IDLE_STATE
if((mmc_cmd(MMC_GO_IDLE_STATE, 0, Finish) & 0x85) != R1_IDLE_STATE)
return 1;
// wysłanie komendy SEND_OP_COND
while(mmc_cmd(MMC_SEND_OP_COND, 0, Finish) != 0);
// ustawienie długości bloku danych na 512 bajtów
mmc_cmd(MMC_SET_BLOCKLEN, 512, Finish);
sendText("\nINFO: Inicjalizacja poprawana");
return 0;
}
zapis do karty
u08 mmc_write_sector(u32 sector)
{
u16 i;
if(mmc_cmd(MMC_WRITE_BLOCK, sector << 9, Leave) != 0)
return(1);
sendText("\nINFO: Karta odpowiedziala na komende, wysylam pusty bajt i Data Token 0xFE");
spi_tx_rx(0xff); // wyślij pusty bajt
spi_tx_rx(0xFE); // wyślij „data token”
for(i=0 ; i<512 ; i++) // wyślij 512 bajtów danych
spi_tx_rx(mmc_sbuf);
spi_tx_rx(0xff); // wyślij 1 bajt CRC (ignorowany przez kartę)
spi_tx_rx(0xff); // wyślij 2 bajt CRC
IOSET1 |= 1 << 23; //zapala diodke
//while((spi_tx_rx(0xff) & 0x1F) != 0x05){ sendText("\nCzekam na data response: "); sendHex(spi_tx_rx(0xff));} // odbierz potwierdzenie (data response)
//IOCLR1 |= 1 << 23;
while(!(spi_tx_rx(0xff) == 0xff)); // czekaj na koniec sygnału busy
IOCLR1 |= 1 << 23;//gasi diodke
mmc_finish(); //koniectransakcji
return 0;
}
odczyt z karty
u08 mmc_read_sector(u32 sector)
{
u16 i;
if(mmc_cmd(MMC_READ_SINGLE_BLOCK, sector << 9, Leave) != 0)
return(1);
sendText("\nINFO: Karta odpowiedziala. Teraz czytam read_tag: ");
if(read_tag()) // czekaj na „data token”
return(1);
for(i=0 ; i<512 ; i++) // odczyt 512 bajtów danych
mmc_sbuf = spi_tx_rx(0xff);
flush_mmc(2); //odrzućCRC
mmc_finish(); //zakończtransakcję
return 0;
}
sprawdzenie czy Data Token
u08 read_tag(void) // oczekiwanie na „data token” czyli
{ // bajt startu bloku danych
u08 tmp;
while(1)
{
tmp = spi_tx_rx(0xff); // odczyt bajtu MMC
sendHex(tmp);//sprawdzenie co odebral z SPI
if(tmp == 0xFE)
{
return 0; // jeśli to jest data token
}
if((tmp & 0xF1) == 1)
{
IOSET1 |= tmp << 16; zapala diodke gdy blad
sendText("\nINFO: Data Error Token");
sendText("\nINFO: Kod bledu odebrany przez SPI: 0x");
sendHex(tmp);
mmc_finish(); //jeśliDataErrorToken
return 1;
}
}
}
void spi_init(void) // inicjalizacja interfejsu SPI
{
/* Configure Pin Connect Block */
PINSEL0 |= 0x5500;
/* Set pclk to same as cclk */
//VPBDIV=0x1;
/* Set to highest speed for SPI at 10 MHz- > 1.25 MHz */
S0SPCCR=248;
/* Device selected as master */
S0SPCR=0x30;
IODIR0 &=~(1<<5); //Setzen von Pin MMC_DI auf Input
IODIR0 |= (1<<4); //Setzen von Pin MMC_Clock auf Output
IODIR0 |= (1<<6); //Setzen von Pin MMC_DO auf Output
IODIR0 |= (1<<23); //Setzen von Pin MMC_Chip_Select auf Output
IODIR0 |= (1<<7);
}
inicjalizacja karty
u08 mmc_reset(void)
{
sbi(MMC_DDR, MMC_CS); // linia portu CS jako wyjście
sbi(MMC_PORT_DIS, MMC_CS); // CS wysoki
spi_init(); // inicjalizacja SPI
flush_mmc(10); //80pustychcyklizegarowych
// wysłanie komendy GO_IDLE_STATE
if((mmc_cmd(MMC_GO_IDLE_STATE, 0, Finish) & 0x85) != R1_IDLE_STATE)
return 1;
// wysłanie komendy SEND_OP_COND
while(mmc_cmd(MMC_SEND_OP_COND, 0, Finish) != 0);
// ustawienie długości bloku danych na 512 bajtów
mmc_cmd(MMC_SET_BLOCKLEN, 512, Finish);
sendText("\nINFO: Inicjalizacja poprawana");
return 0;
}
zapis do karty
u08 mmc_write_sector(u32 sector)
{
u16 i;
if(mmc_cmd(MMC_WRITE_BLOCK, sector << 9, Leave) != 0)
return(1);
sendText("\nINFO: Karta odpowiedziala na komende, wysylam pusty bajt i Data Token 0xFE");
spi_tx_rx(0xff); // wyślij pusty bajt
spi_tx_rx(0xFE); // wyślij „data token”
for(i=0 ; i<512 ; i++) // wyślij 512 bajtów danych
spi_tx_rx(mmc_sbuf);
spi_tx_rx(0xff); // wyślij 1 bajt CRC (ignorowany przez kartę)
spi_tx_rx(0xff); // wyślij 2 bajt CRC
IOSET1 |= 1 << 23; //zapala diodke
//while((spi_tx_rx(0xff) & 0x1F) != 0x05){ sendText("\nCzekam na data response: "); sendHex(spi_tx_rx(0xff));} // odbierz potwierdzenie (data response)
//IOCLR1 |= 1 << 23;
while(!(spi_tx_rx(0xff) == 0xff)); // czekaj na koniec sygnału busy
IOCLR1 |= 1 << 23;//gasi diodke
mmc_finish(); //koniectransakcji
return 0;
}
odczyt z karty
u08 mmc_read_sector(u32 sector)
{
u16 i;
if(mmc_cmd(MMC_READ_SINGLE_BLOCK, sector << 9, Leave) != 0)
return(1);
sendText("\nINFO: Karta odpowiedziala. Teraz czytam read_tag: ");
if(read_tag()) // czekaj na „data token”
return(1);
for(i=0 ; i<512 ; i++) // odczyt 512 bajtów danych
mmc_sbuf = spi_tx_rx(0xff);
flush_mmc(2); //odrzućCRC
mmc_finish(); //zakończtransakcję
return 0;
}
sprawdzenie czy Data Token
u08 read_tag(void) // oczekiwanie na „data token” czyli
{ // bajt startu bloku danych
u08 tmp;
while(1)
{
tmp = spi_tx_rx(0xff); // odczyt bajtu MMC
sendHex(tmp);//sprawdzenie co odebral z SPI
if(tmp == 0xFE)
{
return 0; // jeśli to jest data token
}
if((tmp & 0xF1) == 1)
{
IOSET1 |= tmp << 16; zapala diodke gdy blad
sendText("\nINFO: Data Error Token");
sendText("\nINFO: Kod bledu odebrany przez SPI: 0x");
sendHex(tmp);
mmc_finish(); //jeśliDataErrorToken
return 1;
}
}
}
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości