Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[ATmega8][Asembler] komunikacja z kartą mmc

Maślakmj 06 Apr 2010 17:49 1392 3
  • #1
    Maślakmj
    Level 13  
    Witam, za zadanie mam zaprojektować układ czegoś przypominającego dyktafon, wykorzystującego kartę pamięci, wybór padł na mmc ponieważ w EP był artykuł na temat komunikacji z tą kartą, po dokładnym przestudiowaniu artykułu napisałem już część programu która powinna bez problemu rozpocząć komunikację z kartą. Jednak karta nie chce "wyjść" ze stanu IDLE (bit 0, w odpowiedzi R1 na komendę CMD1 powinien wynosić 0) i karta uparcie odpowiada mi 01111111. (dioda podczepiona pod PORTC, 2 nie zapala się...
    Poniżej zamieszczam swoje wypociny:
    
    .include "m8def.inc"
    .cseg
    .def temp=R16
    .def temp1=R17
    .def odsd=R18
    .def comenda=R19
    .def adresL=R20
    .def adresH=R21
    .def crc=R22
    .def dane=R23
    .org 0x00
    rjmp start
    .org 0x08 rjmp start
    .org 0x09 reti
    
    start:						;||||||USTAWIENIA PORTÓW IPT|||||||
    	sei
    	ldi temp, 123
    	out spl, temp
    ;MOSI i SCK jako wyjścia
    	ldi R16, (1<<3)|(1<<5)|(1<<2)
    	out DDRB, R16
    ;włączone SPI, jako master i zegar SPI na 1/2 oscylatora
    	ldi R16, (1<<4)|(1<<6)
    	out SPCR, R16
    ;port c jako wyjścia diod plus PAC
    	ldi R16, 0b00011111
    	out DDRC, R16
    	out PORTC, R16
    	ldi temp, 0b00000011
    	out PORTB, temp
    							;|||||||PODPROGRAMY ITP|||||||||
    rjmp ini
    
    nic:						;nieskończona petla nic nierobiąca
    nop
    rjmp nic
    
    czekaj:						;SPI wysyła bajta i wraca
    	SBIS SPSR, SPIF
    	rjmp czekaj
    	ret
    
    wyslij:						;SPI wysyła odpowiednia komende
    	out SPDR, comenda
    	rcall czekaj
    	out SPDR, temp
    	rcall czekaj
    	out SPDR, temp
    	rcall czekaj
    	out SPDR, adresH
    	rcall czekaj
    	out SPDR, adresL
    	rcall czekaj
    	out SPDR, crc
    	rcall czekaj
    
    czeknaodp1: 				;czekaj na odpowiedź R1
    	ldi R16, 0xFF
    	out SPDR, R16
    	rcall czekaj
    	in odsd, SPDR
    	cpi odsd, 0				;porównaj do zera(nie mogą byś same zera)
    	breq czeknaodp1
    	sbrs odsd, 7			;w odpowiedzi R1 bit 7 zawsze jest zerem
    	reti	
    rjmp czeknaodp1
    
    czeknaodp2: 				;czekaj na odpowiedź 0xFF
    	ldi R16, 0xFF
    	out SPDR, R16
    	rcall czekaj
    	in odsd, SPDR
    	cpse odsd, temp	
    rjmp czeknaodp2
    reti
    
    czeknaodp3: 				;czekaj na odpowiedź 0xFE
    	ldi temp1, 0xFE
    	ldi R16, 0xFF
    	out SPDR, R16
    	rcall czekaj
    	in odsd, SPDR
    	cpse odsd, temp1	
    rjmp czeknaodp3
    reti
    
    czeknaodp4: 				;czekaj na odpowiedź 0x00 (BUSY)
    	ldi temp1, 0x00
    	ldi R16, 0xFF
    	out SPDR, R16
    	rcall czekaj
    	in odsd, SPDR
    	cpse odsd, temp1	
    rjmp czeknaodp4
    reti
    
    dzibajt:
    sbi PORTB,2					;wysoki stan na CS i 10 x FF
    ldi temp1, 10
    inicjalizacja:
    	ldi R16, 0xFF
    	out SPDR, R16
    	rcall czekaj
    	dec temp1
    	brne inicjalizacja
    	cbi PORTB, 2
    	reti
    
    jedbajt:					;wysoki stan na CS i 8 cykli
    	sbi PORTB, 2
    	ldi R16, 0xFF
    	out SPDR, R16
    	rcall czekaj
    	cbi PORTB, 2
    reti
    
    ini:				;||||||||INICJALIZACJA WŁAŚCIWA|||||||||||||
    CMDO:						;komenda zerowania karty MMC
    	rcall dzibajt
    	ldi comenda, 0x40
    	ldi temp, 0x00
    	ldi adresH, 0x00
    	ldi adresL, 0x00
    	ldi crc, 0x95
    	rcall wyslij
    	cbi portc, 0
    CMD1:						;Uruchomienie inicjalizacji karty
    	rcall jedbajt
    	ldi comenda, 0x41
    	ldi temp, 0x00
    	ldi adresH, 0x00
    	ldi adresL, 0x00
    	ldi crc, 0x95
    	rcall wyslij
    	cbi portc, 1
    sbrc odsd, 0				;czy karta jest w stanie IDLE 
    rjmp ini
    	cbi portc, 2
    CMD16:						;deklaracja długości bloku danych
    	ldi comenda, 0x50
    	ldi temp, 0x00
    	ldi adresH, high (512)
    	ldi adresL, low (512)
    	ldi crc, 0x95
    	rcall wyslij
    	sbi portc, 2
    	sbi portc, 1
    

    ...
    Ps: Tak wiem, że ten temat był wałkowany setki razy,
    Tak wiem, że łatwiej było by w C czy Bascomie, ale im trudniej tym ciekawiej ;)

    Proszę umieścić kod w odpowiednich znacznikach.
    Robak
    [code]
  • #2
    asembler
    Level 32  
    Ja sie nie znam ale po pierwsz to nie mozna zostawic rejestrów w dwuznacznej sytuacji to moze dzialac raz a drugi raz juz nie (SPH)
    Po drugie to treba wysłac troche wiecej tych zegarowych impulsow przed wysłanie rozkazy wyjdz z idle (tak z doswiadczenia to ja daje duzo wiecej rózne karty róznie reagują)
    Ustawienie SPI podczas inicjalizacji nie moze byc taktowane tak wysoko ustaw jak najnizej koncówka 3 w rejstrze spcr
    Po wyslaniu samych zegarków odczekaj chwilke i wysli komende 0 (nie widze tego w programie)
    Nie rozumiem dlaczego kazda procedurka monczy sie RETI?
    A tak w ogole to skopany program raczej bardziej niz dzialka a szkoda:-)
  • #4
    Maślakmj
    Level 13  
    Problem inicjalizacji już rozwiązałem, błąd bym w tym, że oczekując na odpowiedź R1, nie brałem tego pod uwagę, ze po przejściu w stan idle odpowiedź wynosić będzie zero, a program czeka na coś innego od zera... pozdrawiam
    jak dokończę program i wszystko działać będzie bez zarzutów to wyślę, może komuś się przyda