logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[MMC/SD w trybie SPI] - Format ramki komendy.

vcd_a 01 Mar 2009 21:00 4221 12
  • #1 6223447
    vcd_a
    Poziom 18  
    Witam, walczę już z kartą SD/MMC już kolejny dzień, udało mi się uruchomić kartę w trybie SPI za pomocą kodu ze strony captain.at
    Próbuję teraz dokładnie dowiedzieć się jak działa cały program, ale mam duży problem z dojściem do tego jaki jest dokładny format ramki komendy, którą wysyłamy do karty. Szukałem w dokumentacji, ale niestety nie udało mi się tego odszukać.

    Autor z w/w strony używa takiej oto funkcji do wysłania komendy:
    
    char Command(char befF, uint16_t AdrH, uint16_t AdrL, char befH )
    {	// sends a command to the MMC
    	SPI(0xFF);
    	SPI(befF);
    	SPI((uint8_t)(AdrH >> 8));
    	SPI((uint8_t)AdrH);
    	SPI((uint8_t)(AdrL >> 8));
    	SPI((uint8_t)AdrL);
    	SPI(befH);
    	SPI(0xFF);
    	return SPI(0xFF);	// return the last received character
    }
    


    Chciałbym się teraz zapytać, co to są: befF, befFH Jak te befF/befH przenoszą się na to jaką komendę wysyłamy(CMD0/CMD1 itd.)

    Zakładam ten temat, bo szukam odpowiedzi na to pytanie już kilka dni i nie mam czasu na dalsze próbowanie odszukania odpowiedzi ;-)

    Pozdrawiam Krzysiek
  • Pomocny post
    #2 6223946
    pepociufakers
    Poziom 12  
    befF - komenda
    befH - CRC
    na tym etapie nie mamy jeszcze doczynienia z CMD0 i CMD1, poprostu jest to wysłanie jednej ramki rozkazu

    [KOMENDA][U32 ADRES -na 4 bajtach][CRC]+po kazdej komendzie wystawia sie na SPI dodatkowo 0xFF czyli czeka sie jedną ramke i pozniej odbiera odpowiedz
    z tym że - są komende ktore odpowiadają dwoma bajtami, a nie jednym-już nie pamiętam jakie to były - dlatego ->

    polecam Elektronike Praktyczna
    numer 12/07 i 01,02,03/08
    kompletny opis programowania pamięci SD wraz z kodami
  • #3 6223974
    vcd_a
    Poziom 18  
    Mógłbyś podzielić się tymi artykułami z EP?, pozdrawiam Krzysiek

    Jeżeli mówisz, że na tym etapie nie mamy doczynienia z CMD0 itd. to kiedy zaczynami mieć z nimi doczynienia?, pozdrawiam Krzysiek
  • Pomocny post
    #4 6224046
    pepociufakers
    Poziom 12  
    Cytat:
    Jeżeli mówisz, że na tym etapie nie mamy doczynienia z CMD0 itd. to kiedy zaczynami mieć z nimi doczynienia?


    W momencie inicjalizacji - z tego co pamietam CMD0 i CMD1 to sa nazwy symboliczne komend inicjalizujacych kartę SD.
    Przypominij mi się na maila - jutro podesle Ci artykuły - tam bedziesz miał to wytłumaczone jasno i pięknie:)
    pzdr.
  • #5 6224128
    vcd_a
    Poziom 18  
    Ok, już mniej więcej rozumiem o co chodzi ;-)

    Ale jakbyś mi mógł tutaj jeszcze pomóc z tym kodem, jest to inicjalizacja karty MMC:
    
    int MMC_Init(void) // Init SPI
    {
    	unsigned char i;
    	
    	PORTB |= (1 << SPICS); // disable MMC
    	
    	// start MMC in SPI mode
    	for(i=0; i < 10; i++)
    		SPI(0xFF); // send 10*8=80 clock pulses
    	
    	PORTB &= ~(1 << SPICS); // enable MMC
    
    	if (Command(0x40,0,0,0x95) != 1) // reset MMC
    		return 0;
    
    	while(Command(0x41,0,0,0xFF) !=0);
    	return 1;
    }
    


    Podejrzewam, że (Command(0x40,0,0,0x95) != 1) to CMD0 - czyli reset kart. Tak więc co oznaczają wartości 0x40 i 0x95? Jak je powiązać z tym, że to CMD0?, jak obliczyć te wartości np. dla CMD16?

    Moje jeszcze kolejne pytanie brzmi:
    skoro format ramki komendy to:

    [komenda][adres][CRC]

    To po co jest wysyłane w kodzie komendy:
    
    	SPI(0xFF); // Po co tutaj wysyłać 0xFF?
    	SPI(befF); // Tutaj leci komenda
    	SPI((uint8_t)(AdrH >> 8)); // Adres
    	SPI((uint8_t)AdrH);
    	SPI((uint8_t)(AdrL >> 8));
    	SPI((uint8_t)AdrL);
    	SPI(befH); // Tutaj leci CRC
    	SPI(0xFF); // Po co tu 0xFF?
    	return SPI(0xFF); // Po co tutaj 0xFF?
    


    Pozdrawiam i dzięki za odpowiedzi, Krzysiek
  • Pomocny post
    #6 6224772
    pepociufakers
    Poziom 12  
    vcd_a - w temacie artykułów przeczytaj maila
    w temacie kodów
    -zamieszczam tutaj kody ktorych ja użyłem przepisane z ep03/08 z biblioteką spi na at90can128(kompatybline z innymi AVR),
    -a takze kody na at91sam7s z ep05/08 (nie testwalem),
    -i siakieś inne kody- bardzo fajnie napisane, ale ja ich już nie testowałem - ale tam jest dobrze wyszczegolniona roznica miedzy inicjalizacją mmc- a sd.

    Ja polecam wykorzystać juz teraz pamięc SD [inicjalizacja SD i MMC jest inna].

    Wydaje mi sie ze to powinno rozwiac wątpliwosci - jak cos wal z pytaniami.


    pzdr.

    ps. co do Twojego pytania o te 0xFF -
    1) 0xFF na samym poczatku - nie wiem czemu on wysyla te 0xFF na poczatku - niestety nie dotarłem do specyfikacji wymiany danych w pamieci SD - w innych kodach nie spotakłem tego typu podejscia
    2)0xFF nastepne - podobnie - po kiego grzyba to ja nie wiem;)
    3)
    Cytat:
    return SPI(0xFF); // Po co tutaj 0xFF? 

    oczekujesz na przyjscie odpowiedzi-> wiec wysylasz na magisrale spi zegar wysylajac dane -0xFF, dzieki tym 0xFF utrzymujesz na linii MOSI stan wysoki (w momencie otrzymywania danych z SD stan na wejsciowej linii SPI pamieci SD musi byc wysoki - wiec wysylasz na tą linie same jedynki)
  • Pomocny post
    #7 6227486
    markosik20
    Poziom 33  
     SPI(0xFF); // Po co tutaj wysyłać 0xFF? - [b]takie pseudo czekanie gdyby karta jeszcze "nie była gotowa" , przeważnie 8taktów wystarczy;[/b]
       SPI(befF); // Tutaj leci komenda
       SPI((uint8_t)(AdrH >> 8)); // Adres
       SPI((uint8_t)AdrH);
       SPI((uint8_t)(AdrL >> 8));
       SPI((uint8_t)AdrL);
       SPI(befH); // Tutaj leci CRC
       SPI(0xFF); // Po co tu 0xFF? - [b]przygotowanie aż karta przygotuje odpowiedź;[/b]
       return SPI(0xFF); // Po co tutaj 0xFF?  - [b]zwraca odpowiedź karty Response[/b]


    w/w kod niestety jest napisany dla jednej konkretnej karty i w ogóle nie uwzględnia róźnic jakie mogą między nimi wystąpić.

    U8 MMCCommand(U8 command,U32 argument)
    {
    	   U8 res;
    	   U16 repeat=0;
    
    	   if(command!= MMC_STOP_TRANSMISSION)//||command!=READ_MULTI_BLOCK)
    	      {
    		  	 do{res=spi_soft(0xFF);
    	       		if(++repeat>400){return res;}
    	  		 }while(res!=0xFF);
    		  }
    
    	   spi_soft(0x40 | command); //specyfikacja wymaga ustawienia bitu 6 (0x40)
    	   spi_soft(argument >> 24);
    	   spi_soft(argument >> 16);
    	   spi_soft(argument >> 8);
    	   spi_soft(argument);
    	   //if(command == 0x40){spi_soft(0x95);}                           // CRC + additional bit0
    	   spi_soft(0x95);
    
    
    	   repeat=0;
    	   do {
    		   res = spi_soft(0xFF);
    	       if(++repeat>400)
    	       {
    	    	   return res=0x1A;
    
    		   }
    	   	  } while (res == 0xFF);
    	   //if(command!=READ_SINGLE_BLOCK&&command!=READ_MULTI_BLOCK) {res=spi(0xFF);}
    
    	   return res;
    
    }
    
    
  • #8 6228603
    vcd_a
    Poziom 18  
    Witam, dziękuję Panowie za odpowiedzi, teraz zabieram się za lekturę artykułów z Elektroniki Praktycznej, jeżeli będę miał kolejne pytania będę pisał, pozdrawiam Krzysiek
  • #10 6237505
    vcd_a
    Poziom 18  
    @pepociufakers
    Witam, masz może oryginalne kody z Elektroniki Praktycznej do numeru 3/2008?(nie ma na ich stronie ;/), chciałbym napisać teraz swoją bibliotekę i posłużyć się kodami z EP, pozdrawiam Krzysiek
  • Pomocny post
    #11 6238876
    pepociufakers
    Poziom 12  
    vcd_a - kody sam przepisywalem - sa tutaj udostepnione w katalogu "biblioteki moje" to sa przepisane kody z malymi zmianami jesli chodzi o komunikaty magistrali SPI
  • #12 6253220
    vcd_a
    Poziom 18  
    Witam, mam teraz takie pytanie co do zapisu większej ilości danych. Chodzi mi o taki przypadek: w ramce komendy wysyłamy adres na 4bajtach z czego adres początkowy jest zapisany na dwóch młodszych bajtach, czyli maksymalna wartość to tyle ile możemy mieć z uint16_t -> 65 536. A co jeżeli mam "dużą" kartę i chcę zapisać np. pod adres 0x19000 = 102 400(dec)., a to już przekracza naszego biednegp uint16_t? Pozdrawiam Krzysiek ;-)
  • Pomocny post
    #13 6261874
    rpal
    Poziom 27  
    Z mojego podwórka podpowiem koledze (niedawno walczyłem także z MMC/SD) że na początek trzeba sobie zrobić przyzwoity interface i naprawdę upewnić się że działa ! W razie czego służe schematem i PCB który przy okazji zrobiłem :) Ale myślę że to już masz. Stronę kapitana odradzam bo tam za wiele nie znajdziesz natomiast ELM podaje przykłady oprogramowania na ATMEGA 128 więc konieczne będą gruntowne zmiany w programach jesli używaż czegoś innego. Poza tym natychmiast pojawi się się tobie apetyt na system FAT a ELM używa tyle pamięci ram że tylko wspomniane procesory temu podołają. Poszukaj na stronie Martina Thomasa tak się chyba ten koleś nazywa, tam w zasadzie jest wszystko co trzeba, łacznei z łopatologicznym wytłumaczeniem działania użytych komend.
REKLAMA