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

Atmega128 i karta SD

budzik1678 29 Maj 2009 17:05 2130 8
REKLAMA
  • #1 6590444
    budzik1678
    Poziom 10  
    Witam wszystkich. Piszę bo jak wszyscy mam problem. Robię odtwarzacz Mp3 na karty SD. Płytka działa komunikuje się z kartą SD ale nie mogę czytać sektorów. Karta działa dobrze bo odczytuję wszystkie rejestry. Wygląda to tak komendą cmd16 ustawiam na 512B a komendą cmd17 odczytuje blok danych i tu pojawia się problem. Karta odsyła R1=20 czyli błąd adresu (próbowałem z wieloma adresami). Zmieniłem na 256B i działa ale nie do końca. Odczytuje sektor 00, 02, 04 wszystkie parzyste (co 512B) ale gdy chcę odczytać 01, 03 ponownie wyskakuje błąd adresu. W ten sposób mogę odczytać tylko pierwszą część bloku czyli 256B. Karta odsyła tylko 256B przy ustawieniu na 256B. Czyli niby dobrze a co z blokami 01, 03 itd. Czytałem w necie i nic co by do tego pasowało nie znalazłem. Jaka jest tego przyczyna?
  • REKLAMA
  • #2 6590601
    markosik20
    Poziom 33  
    Pokaż funkcję wysyłania komend.
  • #3 6590662
    budzik1678
    Poziom 10  
    cmd17: ;READ SINGLE BLOCK
    sbi $12,7
    ldi r16,$ff
    out $0f,r16
    cbi $12,7
    ldi r16,$51
    sts $01a0,r16
    adres dodawany jest w innym miejscu
    call crc7
    call send_spi48
    call resp_spi
    lds r16,$01a8
    cpi r16,$00
    brne rd_err
    ldi r26,$00
    ldi r27,$06
    ldi r17,$02
    ldi r18,$08
    call read_spi
    ret 




    Dodano po 5 [minuty]:

    Funkcje wysyłania są dobre bo odczyt CID CSD jest na nich zrobiony a działa ok.
    Proszę używać znaczników [code]
    [zumek]
  • REKLAMA
  • #4 6590718
    markosik20
    Poziom 33  
    No i "amba" :(. Na podstawie kilkunastu rozkazów to nic nie można stwierdzić.
    Jak zamieścisz dłuższy kod to nikomu się nie będzie chciało domyślać o co Ci chodziło.
    Takie niestety są uroki pisania w ASM , niby wiadomo dokładnie co się robi ale nie do końca wiadomo dlaczego nie działa :wink:.
  • REKLAMA
  • #5 6590758
    budzik1678
    Poziom 10  
    Kod tu nie wiele pomoże bo jest dobry (wszystkie inne odczyty działają). Odczyty CID i CSD zrobione są identycznie jedynie miejsce zapisu odczytanych danych i ilosc sie zmienia...
  • REKLAMA
  • #6 6590846
    djbpm
    Poziom 23  
    Witam
    Czemu sobie (i nam) utrudniasz życie, i zamiast napisać
    sbi PORTD, 7 piszesz sbi $12,7 ?
    Może jednak ten kod nie jest do końca dobry, nie wiem jak wygląda reszta.
    Mój kod, który działa:

    //*****************************************************************************
    // Function: sd_read_sector
    // Parameters: Byte number in data2H data2L dataH dataL
    //             pointer to Data buffer in Z
    // Returns: "data"=0 ok, "data"=!0=error
    //
    // Description: Read data from one sector
    //*****************************************************************************
    sd_read_sector:
    push	temp
    push	temp2
    
    ser		data
    rcall 	sd_sendreceivebyte			// dummy byte
    cbi		sd_port,	sd_cs			// select SD card
    
    ldi		data,	SD_READ_SINGLE_BLOCK
    rcall	sd_command
    tst		data
    brne	sd_read_sector_ret			// if error
    
    rcall	sd_wait_for_reply			// wait for card to be ready to read data
    
    ldi		temp2,	2
    ldi		temp,	0
    sd_read_sector_loop:
    ser		data
    rcall	sd_sendreceivebyte
    st		z+,	data
    dec		temp
    brne 	sd_read_sector_loop
    dec		temp2
    brne 	sd_read_sector_loop
    
    clr		data
    
    sd_read_sector_ret:
    
    sbi		sd_port,	sd_cs		// deselect SD card
    ser		data					// send dummy byte
    rcall	sd_sendreceivebyte		
    
    pop		temp2
    pop		temp
    ret

    Uwagi:
    SD_READ_SINGLE_BLOCK = 0x51
    sd_sendreceivebyte = wysyła na spi bajt z rejestru "data" i zwraca w "data" bajt odpowiedzi
    sd_command= wysyła polecenie do karty w rejestrze "data" a argumenty tego polecenia są w rejestrach data2H data2L dataH dataL (np numer sektora)
    sd_wait_for_reply= wysyła ciągle FF do karty i czeka aż jej odpowiedź będzie inna niż FF.
    Jakiego układu użyjesz jako dekodera mp3?
    Pozdrawiam, powodzenia
  • #7 6591164
    budzik1678
    Poziom 10  
    Do mp3 użyje układu VS1011E. Mi się wydaje że może kolejnośc komend jest niewłasciwa. Ja wysyłam tak. Jak już R1=00 to wysyłam cmd58, cmd10, cmd9, cmd16(argument 00 00 02 00), cmd13 i teraz wysyłam cmd17 która odpowiada mi R1=20. Wszystkie komendy przed cmd17 odpowiadają R1=00

    PS. A co do utrudnaiania życia. Ja od zawsze tak pisałem (nawyk) i dla mnie nie stanowi to problemu. Za mało siedzę zeby zmieniac nawyki:D
  • Pomocny post
    #8 6591321
    djbpm
    Poziom 23  
    Ja robię inicjalizację w ten sposób:
    1. Zegar SPI na najwolniejszy
    2. karta przez CS nie wybrana
    3. Wysyłam 20 bajtów 0xFF
    4. Wysyłam rozkaz GO_IDLE_STATE, (z wyborem CS) aż dostanę odpowiedź R1_IDLE_STATE (limit prób 100)
    5. Wysyłam rozkaz SD_SEND_OP_COND, (z CS) limit prób 255, aż będzie odpowiedź 0
    6. Wyłączam CRC (może u ciebie jest problem z obsługą crc i dlatego zgłasza błąd?)
    7. SD_SET_BLOCKLEN 512.
    8. SPI duża prędkość - i już działa

    aa jeszcze mi do głowy przyszedł 1 pomysł, jaki podajesz ten adres? bo to jest numer bajtu, ale w zaokrągleniu do sektora, czyli 0, 512, 1024, 1536, 2048, 2560 itd....
  • #9 6593282
    budzik1678
    Poziom 10  
    Znalazłem :D Przed cmd17 trzeba wysłać kilka zegarów przy CS=1... Wszystkim dzięki za pomoc...
REKLAMA