Forum: Mikrocontroller und Digitale Elektronik SD Karte via ATmega644 und SPI ansprechen


von Flo (Gast)


Lesenswert?

Hallo,

ich habe derzeit ein Projekt, in dem ich eine SD-Karte ansprechen will.

Meine Testumgebung ist ein MyEthernet 2.03 Board und einer UART ausgabe 
zum printf debuggen via MySmartUSB.

Die Uart Ausgabe klappt auch ganz gut. Und SPI funktioniert auch soweit, 
da das auslesen der MAC-Addresse vom ENC28j60 funktioniert.


Nun habe ich aber Probleme die SD-Karte anzusprechen. Laut Schaltplan 
ist der Chipselect C6 und den benutze ich auch, von daher scheint hier 
nicht mein Problem zu liegen.


Aber erst einmal zu meinem Problem.

Ich versuche die Karte zu Initialisieren indem ich erst 74 Clocks lang 
0xFF sende und anschließend mit CMD55 und ACMD41 versuche die Karte zu 
starten.

sd.h:
1
#ifndef __SDCARD__
2
#define __SDCARD__
3
4
/* Includes */
5
#include "../uart/uart.h"
6
#include "../spi/spi.h"
7
#include "config.h"
8
9
/* SPI */
10
#ifndef SPI_PORT
11
    #define SPI_PORT PORTB
12
#endif
13
14
#define CS_SD PC6  //
15
16
/* Chip select for SD-Card */
17
#define cs_low() SPI_PORT &= ~(1 << CS_SD)
18
    
19
#define cs_high() SPI_PORT |= (1 << CS_SD)
20
21
/*Methods*/
22
void sd_init(void);   
23
void sd_send_command();
24
#endif


sd.c:
1
#include "sd.h"
2
3
/*Methods*/
4
5
void sd_init(){
6
    cs_low();
7
    /*Synchronizing SDCard and SPI by sending 74Clocks a logical 1*/
8
    for(int count=0; count<74; count++)
9
        spi_transmit(0xFF);
10
    printf("CMD55:\n");
11
    printf("Gesendet: 0x77, Empfangen: %x\n",spi_transmit(CMD55));
12
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
13
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
14
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
15
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
16
    printf("Gesendet: 0x01, Empfangen: %x\n",spi_transmit(0x01));
17
    printf("ACMD41:\n");
18
    /*send CMD55 to notify that next cmd is an application specific cmd*/
19
    printf("Gesendet: 0x77, Empfangen: %x\n",spi_transmit(ACMD41));
20
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
21
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
22
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
23
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
24
    printf("Gesendet: 0x01, Empfangen: %x\n",spi_transmit(0x01));
25
26
    printf("Antwort:\n");
27
    printf("Gesendet: 0x00, Empfangen: %x\n",spi_transmit(0x00));
28
    cs_high(); 
29
}


config.h:
1
#define SDHC_SUPPORT 0 // 1 = Host supports High Capacity Cards | 0 = no support for SDHC-Cards
2
3
/* 
4
Command Format (6 Bytes long): 
5
start bit ('0') + transmission bit('1') + command index (6bit) + arguments (4 byte) + CRC7 (7bit)+ end bit('1')
6
*/
7
8
/*SPI specifik commands (start bit+transmission bit+command index):*/   
9
#define CMD0  0x40 //GO_IDLE_STATE
10
#define CMD1  0x41 //SEND_OP_COND
11
#define CMD9  0x49 //SEND_CSD
12
#define CMD10 0x4A //SEND CID
13
#define CMD12 0x4C //STOP_TRANSMISSION
14
#define CMD13 0x4D //SEND_STATUS
15
#define CMD16 0x50 //SET_BLOCKLEN
16
#define CMD17 0x51 //READ_SINGLE_BLOCK
17
#define CMD18 0x52 //READ_MULTIPLE_BLOCK
18
#define CMD24 0x58 //WRITE_BLOCK
19
#define CMD25 0x59 //WRITE_MULTIPLE_BLOCK
20
#define CMD27 0x5B //PROGRAM_CSD
21
#define CMD28 0x5C //SET_WRITE_PROT       
22
#define CMD29 0x5D //CLR_WRITE_PROT
23
#define CMD30 0x5E //SEND_WRITE_PROT
24
#define CMD32 0x60 //ERASE_WR_BLK_START_ADDR
25
#define CMD33 0x61 //ERASE_WR_BLK_END_ADDR
26
#define CMD38 0x66 //ERASE_WR_BLK_END_ADDR
27
#define CMD42 0x6A //LOCK_UNLOCK
28
#define CMD55 0x77 //APP_CMD
29
#define CMD56 0x78 //GEN_CMD
30
#define CMD58 0x7A //READ_OCR
31
#define CMD59 0x7B //CRC_ON_OFF
32
33
#define ACMD41 0x69//



und SPI:
1
#include "spi.h"
2
#include "../uart/uart.h"
3
4
void SPI_Init(void) {
5
  /* Set MOSI and SCK output, all others input */
6
  DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<SPI_CS);
7
8
  /* Enable SPI, Master */
9
  SPCR = (1<<SPE)|(1<<MSTR);
10
  /* Set clock fck/2 */
11
  SPSR = (1<<SPI2X);
12
13
#ifdef DEBUG
14
  printf("SPI Initialized\n");
15
#endif
16
}
17
18
// returns SPI
19
uint8_t spi_transmit(uint8_t cData) {
20
  /* Start transmission */
21
  SPDR = cData;
22
  /* Wait for transmission complete */
23
  while(!(SPSR & (1<<SPIF)));
24
25
  return SPDR;
26
}

nunja in meiner main ruf ich bis jetzt nur sd_init() auf.


Meine Frage ist nun ist es überhaupt richtig die Karte so initialisieren 
zu wollen?

Das was ich habe, habe ich der 
Part_1_Physical_Layer_Simplified_Specification_Ver_3.01_Final_100518.pdf 
entnommen und sollte meiner meinung nach stimmen, jedoch ist der 
Informationsfluss momentan noch sehr hoch für mich weshalb es auch sehr 
gut sein kann, dass ich mich irre.

Es wäre cool wenn mir einer ein paar tipps zur SDKarte geben könnte. 
Also wie das mit den Commands ist, was ich da beachten muss und ka.

noch eine Frage wäre, ob ich immer eine Antwort im R1 Format bekomme?

mfG Flo

von Flo (Gast)


Lesenswert?

ok also ich hab schonma einen Fehler entdeckt ... das mit dem ENC hab 
ich vorher auf nem pollin board getestet gehabt . . . auf dem MyEthernet 
sind es andere Pins für Miso Mosi und SCK jetzt darf ich mir ersma UART 
als SPI anschaun :P.

von Juergen (Gast)


Lesenswert?

Hallo, da der Code nicht vollständig ist vermutet meine Glaskugel einen 
der Standardfehler. Wenn der SS vom SPI nicht als Ausgang konfiguriert 
wird geht gar nichts. Beim 644 glaube ich PB4. Bitte mal nachsehen!

von Flo (Gast)


Lesenswert?

Danke für den Hinweis ... das war Anfangs ein Fehler als es noch auf dem 
anderen Board getestet wurde. Habe ich dann aber dank der Hilfe meines 
Professors herausgefunden.

Jetzt lag der Fehler erst einmal daran, dass ich das Board gewechselt 
habe zu MyEthernet V2.03 und die SD-Karte an dem UART1 hängt, was man ja 
glücklicherweise als SPI betreiben kann.

Ich werde nun erst einmal versuchen dass ordentlich einzubinden.

Aber hier nochmal der gesamte Code:

main.c :
1
#define F_CPU 20000000L
2
#define BAUD 9600L
3
#define DEBUG
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include "uart/uart.h"
8
#include "spi/spi.h"
9
#include "sd/sd.h"
10
11
int main(void) {
12
  USART_Init();
13
  SPI_Init(); 
14
  SPI2_Init(); //ENC OR SDCard
15
    
16
  //PORTB |= (1<<SPI_CS);
17
    
18
  printf("Welcome to WeSa System v0.0.1a\n");
19
20
  printf("starting -> SD test\n");
21
  
22
  sd_init();
23
  
24
  while(1) {    
25
26
    _delay_ms(500);
27
  }
28
29
  return 0;
30
}

spi.h:
1
/* 
2
   Name: spi.h
3
   Author: Mathäus Sander & Florian Weinhold
4
5
   Desc.: SIP function library for ATmega Prozessors
6
   License: LGPL
7
*/
8
9
#include<avr/io.h>
10
11
#ifndef _SPI_H_
12
#define _SPI_H_
13
14
/*standard SPI*/
15
#define DDR_SPI0 DDRB
16
#define DD_MOSI0 DDB5
17
#define DD_SCK0  DDB7
18
#define DD_CS0   DDB4
19
20
/*UART1 as SPI*/
21
#define DDR_SPI1 DDRD
22
#define XCK1     PD4
23
24
/*chipselects*/
25
#define CS_ENC PD5
26
#define CS_SD  PC6
27
28
#define SPI0_PORT PORTD
29
#define SPI1_PORT PORTC
30
31
/*methods to select */
32
#define select_enc()   SPI0_PORT &= ~(1 << CS_ENC) //sets chip select for EN28j60 to 0
33
#define unselect_enc() SPI0_PORT |= (1 << CS_ENC)  //sets chip select for EN28j60 to 1
34
#define select_sd()    SPI1_PORT &= ~(1 << CS_SD) //sets chip select for SDCard to 0
35
#define unselect_sd()  SPI1_PORT |= (1 << CS_SD)  //sets chip select for SDCard to 1
36
37
// initialize 
38
void SPI_Init(void);   
39
void SPI2_Init( void );
40
// send and recive methode
41
uint8_t spi_transmit(uint8_t);
42
uint8_t spi2_transmit( uint8_t );
43
44
#endif

spi.c:
1
#include "spi.h"
2
#include "../uart/uart.h"
3
4
//Basic SPI
5
void SPI_Init(void) {
6
  /* Set MOSI and SCK output, all others input */
7
  DDR_SPI0 = (1<<DD_MOSI0)|(1<<DD_SCK0)|(1<<DD_CS0);
8
9
  /* Enable SPI, Master */
10
  SPCR = (1<<SPE)|(1<<MSTR);
11
  /* Set clock fck/2 */
12
  SPSR = (1<<SPI2X);
13
14
#ifdef DEBUG
15
  printf("SPI Initialized\n");
16
#endif
17
}
18
19
20
//Uart1 as SPI
21
void SPI2_Init( void )
22
{
23
  UBRR1 = 0;
24
  /* Setting the XCKn port pin as output, enables master mode. */
25
  DDR_SPI1 |= (1<<XCK1);
26
  /* Set MSPI mode of operation and SPI data mode 0. */
27
  UCSR1C = (1<<UMSEL11)|(1<<UMSEL10)|(0<<UCPHA1)|(0<<UCPOL1);
28
  /* Enable receiver and transmitter. */
29
  UCSR1B = (1<<RXEN1)|(1<<TXEN1);
30
  /* Set baud rate. */
31
  /* IMPORTANT: The Baud Rate must be set after the transmitter is enabled
32
  */
33
  UBRR1 = 4;
34
}
35
36
uint8_t spi_transmit(uint8_t cData) {
37
  /* Start transmission */
38
  SPDR = cData;
39
  /* Wait for transmission complete */
40
  while(!(SPSR & (1<<SPIF)));
41
42
  return SPDR;
43
}
44
45
uint8_t spi2_transmit( uint8_t cData )
46
{
47
  /* Wait for empty transmit buffer */
48
  while ( !( UCSR1A & (1<<UDRE1)) );
49
  /* Put data into buffer, sends the data */
50
  UDR1 = cData;
51
  /* Wait for data to be received */
52
  while ( !(UCSR1A & (1<<RXC1)) );
53
  /* Get and return received data from buffer */
54
  return UDR1;
55
}

uart.h:
1
#ifndef F_CPU
2
#define F_CPU 20000000L
3
#endif
4
5
#define BAUD 9600L
6
7
#ifndef DEBUG
8
#define DEBUG
9
#endif
10
11
#include<avr/io.h>
12
#include<util/setbaud.h>
13
#include<stdio.h>
14
15
#ifndef _UART_H_
16
#define _UART_H_
17
18
void USART_Init(void);
19
int uart_putchar(char, FILE *);
20
21
#endif

uart.c:
1
#include "uart.h"
2
3
static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, _FDEV_SETUP_WRITE );
4
5
void USART_Init(void) {
6
  UBRR0 = UBRR_VALUE;
7
8
     UCSR0B = (1<<RXEN0) | (1<<TXEN0);
9
     // Frame Format: Asynchron 8N1
10
     UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
11
12
    stdout = &mystdout;
13
14
#ifdef DEBUG
15
    printf("UART Initialized\n");
16
#endif
17
}
18
19
int uart_putchar(char c, FILE *stream)
20
{
21
    if (c == '\n')
22
        uart_putchar('\r', stream);
23
  
24
  // Busy Waiting
25
    while ( !( UCSR0A & (1<<UDRE0)) );
26
27
    UDR0 = c;
28
29
    return 0;
30
}

sd.h:
1
#ifndef __SDCARD__
2
#define __SDCARD__
3
4
/* Includes */
5
#include "../uart/uart.h"
6
#include "../spi/spi.h"
7
#include "config.h"
8
9
/*Methods*/
10
void sd_init(void);   
11
void sd_send_command();
12
#endif

sd.c:
1
#include "sd.h"
2
3
/*Methods*/
4
5
void sd_init(){
6
    select_sd();
7
    
8
    //Initialize with ACMD41 
9
    
10
    //send Command CMD55 as Prefix for specifik Commands
11
    printf("send: 0x77, recv: %x\n",spi2_transmit(CMD55));
12
    //no parameters
13
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
14
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
15
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
16
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
17
    //endbits
18
    printf("send: 0x01, recv: %x\n",spi2_transmit(0x01));
19
    
20
    //send Command ACMD41
21
    printf("send: 0x77, recv: %x\n",spi2_transmit(ACMD41));
22
    //no parameters
23
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
24
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
25
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
26
    printf("send: 0x00, recv: %x\n",spi2_transmit(0x00));
27
    //endbits
28
    printf("send: 0x01, recv: %x\n",spi2_transmit(0x01));
29
    
30
    
31
    
32
    unselect_sd();
33
34
}  
35
36
}

sd/config.c
1
#define SDHC_SUPPORT 0 // 1 = Host supports High Capacity Cards | 0 = no support for SDHC-Cards
2
3
/* 
4
Command Format (6 Bytes long): 
5
start bit ('0') + transmission bit('1') + command index (6bit) + arguments (4 byte) + CRC7 (7bit)+ end bit('1')
6
*/
7
8
/*SPI specifik commands (start bit+transmission bit+command index):*/   
9
#define CMD0  0x40 //GO_IDLE_STATE
10
#define CMD1  0x41 //SEND_OP_COND
11
#define CMD9  0x49 //SEND_CSD
12
#define CMD10 0x4A //SEND CID
13
#define CMD12 0x4C //STOP_TRANSMISSION
14
#define CMD13 0x4D //SEND_STATUS
15
#define CMD16 0x50 //SET_BLOCKLEN
16
#define CMD17 0x51 //READ_SINGLE_BLOCK
17
#define CMD18 0x52 //READ_MULTIPLE_BLOCK
18
#define CMD24 0x58 //WRITE_BLOCK
19
#define CMD25 0x59 //WRITE_MULTIPLE_BLOCK
20
#define CMD27 0x5B //PROGRAM_CSD
21
#define CMD28 0x5C //SET_WRITE_PROT       
22
#define CMD29 0x5D //CLR_WRITE_PROT
23
#define CMD30 0x5E //SEND_WRITE_PROT
24
#define CMD32 0x60 //ERASE_WR_BLK_START_ADDR
25
#define CMD33 0x61 //ERASE_WR_BLK_END_ADDR
26
#define CMD38 0x66 //ERASE_WR_BLK_END_ADDR
27
#define CMD42 0x6A //LOCK_UNLOCK
28
#define CMD55 0x77 //APP_CMD
29
#define CMD56 0x78 //GEN_CMD
30
#define CMD58 0x7A //READ_OCR
31
#define CMD59 0x7B //CRC_ON_OFF
32
33
#define ACMD41 0x69//


ich glaub das sollten alle wichtigen Quelltexte sein. Funktionieren tut 
es leider immer noch nicht. Wobei ich gerade auch viel am rumprobieren 
bin.

Jedenfalls habe ich das so verstanden, dass wenn ich die Karte so 
initialisieren will eine 1 als Antwort bekomme bis die Karte fertig 
initialisiert ist.

Jedoch kriege ich immer nur 0 raus.

Gibt es einen Wert den ich übermitteln kann, auf den ich direkt einen 
bestimmten Wert als antwort bekomme?

mfG
Flo

von Flo (Gast)


Lesenswert?

ok hab noch einen Fehler ich schalte den Chipselect für die SD Karte 
nicht auf ausgang, habe ich aber jetzt auch geändert. Funktioniert 
trotzdem nicht.

von ikorb (Gast)


Lesenswert?

Damit die Karte in den SPI-Modus wechselt muss sie erstmal ein 
GO_IDLE_MODE-Kommando mit korrekter CRC empfangen, d.h. 0x40 0x00 0x00 
0x00 0x00 0x95. So lange die Karte noch im SD-Modus ist wirst du auch 
keine Antwort sehen, da die dort auf einer anderen Leitung als im 
SPI-Modus geliefert wird.

Im SPI-Modus sind die CRCs dann egal (sofern man sie nicht wieder 
einschaltet), nur bei CMD8 (SEND_IF_COND) muss immer eine korrekte CRC 
mitgeliefert werden wenn man mit einer SDHC-Karte reden will.

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Habe es gestern nun hin bekommen, nach diversen Änderungen an den 
einzelnen Dateien. Woran genau es lag kann ich nicht sagen.

Nun habe ich jedoch noch ein oder 2 Fragen zu den SDHC cards.

Also ... ich sende CMD0 und bekomme eine 0x1 zurück. Dann sende ich 
solange cmd1 bis eine 0 kommt. Dies funktioniert wunderbar. Wenn ich 
jedoch die 4GB karte einlege kommt 0x5 als antwort (illegal Command). 
Was ich dann so interpretier dass CMD1 nicht geht also versuch ichs wenn 
keine 0x1 mehr kommt sondern 0x5 mit ACM41. Ist das richtig? 
Anschließend bekomme ich nur noch 0xFF zurück ... ist die SDHC karte 
dann rdy oder muss die auch irgendwann auf 0 wechseln? Notfalls hab ich 
noch nen timeout eingebaut

Hier mal der Quellcode für die SD Karte sollte ausreichen glaub ich

sd.h:
1
#ifndef __SDCARD__
2
#define __SDCARD__
3
4
/* Includes */
5
#include "../uart/uart.h"
6
#include "../spi/spi.h"
7
8
#ifndef DEBUG
9
  #define DEBUG //Should be only defined if Debug messages are needed
10
#endif
11
/*spi methods*/
12
#define spi_send_byte(x) spi2_transmit(x)   //Method to transmit a Byte via SPI
13
#define spi_speed_low() ;                   //sets SPI Clockrate between 100kHz and 400kHz
14
#define spi_speed_high() ;           //sets SPI Clockrate to maximum
15
16
/*defines for Hardware Initialisation*/
17
#define SD_CS_PIN  PC6    //Chipselect for SD Card
18
#define SD_CS_PORT PORTC  //Port of SD_CS
19
#define SD_CS_DDR  DDRC   //Data Direction Register for SD_CS
20
21
#define sd_low()   SD_CS_PORT &= ~(1 << SD_CS_PIN) // SD_CS -> '1'
22
#define sd_high()  SD_CS_PORT |= (1 << SD_CS_PIN)  // SD_CS -> '0'
23
24
/*some other defines:*/
25
#define SD_INIT_TIMEOUT 20  //value between 0 and 254 
26
#define SDHC_SUPPORT    1   // 0 = SDHC disable, 1 = SDHC enable
27
/* 
28
Command defines:
29
30
Command Format (6 Bytes long): 
31
start bit ('0') + transmission bit('1') + command index (6bit) + arguments (4 byte) + CRC7 (7bit)+ end bit('1')
32
*/
33
34
/*SPI specifik commands (start bit+transmission bit+command index):*/   
35
#define SD_CMD0  0x00 //GO_IDLE_STATE
36
#define SD_CMD1  0x01 //SEND_OP_COND
37
#define SD_CMD9  0x09 //SEND_CSD
38
#define SD_CMD10 0x0A //SEND CID
39
#define SD_CMD12 0x0C //STOP_TRANSMISSION
40
#define SD_CMD13 0x0D //SEND_STATUS
41
#define SD_CMD16 0x10 //SET_BLOCKLEN
42
#define SD_CMD17 0x11 //READ_SINGLE_BLOCK
43
#define SD_CMD18 0x12 //READ_MULTIPLE_BLOCK
44
#define SD_CMD24 0x18 //WRITE_BLOCK
45
#define SD_CMD25 0x19 //WRITE_MULTIPLE_BLOCK
46
#define SD_CMD27 0x1B //PROGRAM_CSD
47
#define SD_CMD28 0x1C //SET_WRITE_PROT       
48
#define SD_CMD29 0x1D //CLR_WRITE_PROT
49
#define SD_CMD30 0x1E //SEND_WRITE_PROT
50
#define SD_CMD32 0x20 //ERASE_WR_BLK_START_ADDR
51
#define SD_CMD33 0x21 //ERASE_WR_BLK_END_ADDR
52
#define SD_CMD38 0x26 //ERASE_WR_BLK_END_ADDR
53
#define SD_CMD42 0x2A //LOCK_UNLOCK
54
#define SD_CMD55 0x37 //APP_CMD
55
#define SD_CMD56 0x38 //GEN_CMD
56
#define SD_CMD58 0x3A //READ_OCR
57
#define SD_CMD59 0x3B //CRC_ON_OFF
58
59
#define SD_ACMD41 0x29//
60
61
#define SD_CMD_MASK 0x40;
62
63
/*Methods*/
64
uint8_t sd_init(void); //initialize SD Card    
65
void sd_hw_init(void); //initialize hardware of SD Card after Power on
66
uint8_t sd_send_cmd(uint8_t, uint16_t, uint16_t, uint8_t); //Sends a 6 Byte long command via SPI
67
68
#endif
--------------------------------------------------------------
sd.c:
1
#include "sd.h"
2
#include <util/delay.h>
3
4
// Method to initialize SDCard/MMC after Powerup
5
// name: sd_init()
6
// @param
7
// @return returns type of inserted Card (0 = no Card / unknown Card, 1 = mmc or SDCv1, 2 = SDCv2)
8
9
uint8_t sd_init(){
10
  spi_speed_low();
11
  
12
  sd_hw_init();
13
  
14
    sd_low(); 
15
    
16
    uint8_t rec = 0;
17
    
18
    //CMD0 to Reset Card
19
    rec = sd_send_cmd( SD_CMD0, 0, 0, 0x94 ); 
20
    
21
  #ifdef DEBUG
22
    if(rec)printf("SDCard is in IDLE mode.\n");
23
  #endif
24
  if(rec){
25
    uint8_t timeout = SD_INIT_TIMEOUT;
26
  
27
    /*
28
     * initialize Card 
29
     * */
30
    while(rec){
31
      if( SDHC_SUPPORT & (rec != 1)){
32
        sd_send_cmd( SD_CMD55, 0, 0, 0 );
33
        rec = sd_send_cmd( SD_ACMD41, 0, 0, 0 );
34
      }else if(rec == 1){
35
        rec = sd_send_cmd( SD_CMD1, 0, 0, 0 );
36
      }
37
      if(!timeout--){  
38
        #ifdef DEBUG
39
          printf("Timeout reached.\n");
40
          if(SDHC_SUPPORT)
41
            printf("Card is an SDHC-Card.\n");
42
          else
43
            printf("not supported Card.\n");
44
        #endif      
45
        break;
46
      }
47
    }
48
     
49
    sd_high(); //deselect SD Card
50
     
51
    #ifdef DEBUG
52
      printf("SDCard initialized.\n");
53
    #endif
54
    
55
    //set SPI CLK up to max
56
    spi_speed_high();
57
    
58
    //Return Card Type
59
    if(!rec) return 1;             //MMC / SD Card v1
60
    else if(rec == 0xFF) return 2; //SDHC
61
    else return 0;                 //not supported
62
  }else{
63
    
64
    #ifdef DEBUG
65
      printf("No or unknown Card.\n");
66
    #endif
67
    
68
    return 0; 
69
  }
70
  
71
}  
72
73
// Initialize Hardware after Poweron 
74
// 1. SD_CS -> output and 1
75
// 2. Wait 1 ms
76
// 3. 74+ dummy clocks
77
//
78
// name: sd_hw_init
79
// @param
80
// @return
81
82
void sd_hw_init(void){
83
  /*Chips select for SDCard to output*/
84
    SD_CS_DDR |= ( 1 << SD_CS_PIN );  
85
    /*CS to logic 1*/
86
    sd_high();
87
  /*wait 1 ms*/
88
  _delay_ms(1);
89
    //send 74+ dummy clocks
90
    for(int i = 0; i<8 ; i++)
91
        spi_send_byte(0xFF);
92
  
93
#ifdef DEBUG
94
    printf("SDCard Hardware initialized.\n");
95
#endif
96
}
97
98
// Sends a command to SDC via SPI and returns R1
99
// name: sd_hw_init
100
// @param cmd command for SD Card
101
// @param paramH first two command parameters as 16Bit unsinged int
102
// @param paramH next two command parameters as 16Bit unsinged int
103
// @param crc checksum
104
// @return command response in R1 format
105
106
uint8_t sd_send_cmd(uint8_t cmd, uint16_t paramH, uint16_t paramL, uint8_t crc){
107
  /*build complete Command*/
108
  uint8_t buffer[6] ;                 //temporary Buffer for the CMD
109
  buffer[0] = cmd | SD_CMD_MASK;      //Set start and transmission bit + Command
110
  buffer[1] = (paramH & 0xff00) >> 8; //Set parameter byte 1
111
  buffer[2] = paramH & 0xff;          //Set parameter byte 2 
112
  buffer[3] = (paramL & 0xff00) >> 8; //Set parameter byte 3
113
  buffer[4] = paramL & 0xff;          //Set parameter byte 4
114
  buffer[5] = crc | 0x01;             //CRC + Endbit '1'
115
116
  #ifdef DEBUG
117
    //Prints the Command
118
    printf("Sending CMD: ");
119
    for(uint8_t i=0; i<6; i++)
120
      printf("0x%x, ", buffer[i]);
121
  #endif
122
  
123
  //Send complete Command via SPI
124
    for(uint8_t i=0; i<6; i++)
125
        spi_send_byte(buffer[i]);
126
  
127
  //Send dummy-byte
128
  spi_send_byte(0xFF);
129
  
130
  uint8_t ret = spi_send_byte(0xFF);
131
  
132
  #ifdef DEBUG
133
    //Prints the Command
134
    printf("recv.: 0x%x", ret);
135
    printf(".\n");
136
  #endif  
137
  //receive byte and return
138
    return ret;
139
}





muss ich bei SDHC karten noch irgendetwas berücksichtigen?

mfG Flo

von ikorb (Gast)


Lesenswert?

Flo W. schrieb:
> muss ich bei SDHC karten noch irgendetwas berücksichtigen?

Nach CMD0 muss ein CMD8 mit korrekter(!) CRC und gesetztem HCS-Bit 
gesendet werden. Wenn die Karte darauf mit einem Fehler antwortet ist es 
eine MMC- oder 1.x-SD-Karte und definitiv keine SDHC. Bei ACMD41 muss 
ebenfalls vom Host das HCS-Bit gesetzt werden (1L<<30). Wenn die Karte 
danach in der Antwort auf CMD58 das passende Bit setzt ist es eine 
SDHC-Karte. Die unterscheiden sich nach der Initialisierung von 
MMC/SD-Karten "nur" noch darin, dass sie bei Lese- und Schreibbefehlen 
keinen Byteoffset sondern eine Sektornummer (512-Byte-Sektoren) haben 
wollen, was bei typischen Implementierungen bedeutet dass man für 
MMC/SD-Karten in den Lese- und Schreibfunktionen die Sektornummer mit 
<<9 shiftet und für SDHC-Karten den Shift weglässt.

Ein bislang recht gut funktionierendes Codebeispiel zur 
SD-Initialisierung findet sich zB unter 
http://www.sd2iec.de/cgi-bin/gitweb.cgi?p=newboot.git;a=blob;f=sdlight.c;h=4a074b4269df972fed0a0f43f8e763caf98beece;hb=HEAD#l166

von holger (Gast)


Lesenswert?

>Ein bislang recht gut funktionierendes Codebeispiel zur
>SD-Initialisierung findet sich zB unter
>http://www.sd2iec.de/cgi-bin/gitweb.cgi?p=newboot....

Aus dem C Code:

   goto not_sd2;


AUAUAUUUAUUAAAAA;)

von ikorb (Gast)


Lesenswert?

holger schrieb:
> Aus dem C Code:
>    goto not_sd2;
>
> AUAUAUUUAUUAAAAA;)

Oops, wie habe ich denn diese Stelle verbrochen? Fixed, der Link zeigt 
allerdings auf eine spezifische Revision der Datei.

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Also noch einmal schritt für Schritt so wie ich das verstanden habe

1. Warten bis Spannung der Karte bei 2.2 V
2. Speed auf 100kHz bis 400kHz setzten
3. Chipselect für Karte auf High
3. 1ms warten
4. 74+ Clocks bei kontinuierlichem senden von 1
5. CS auf low
6. CMD0, ohne Argumente und mit berechneter CRC (0x95) senden
6.1 Wenn eine 1 zurück kommt ist die Karte im IDLE mode
6.2 Wenn eine 0 zurück kommt konnte keine Karte gefunden oder erkannt 
werden
7. CMD8 mit CRC (wie lautet die) und gesetztem HCS bit (heisst bit 30 
das 30.bit von den argumenten her oder vom gesamten command?)
7.1 Bei Fehler ist es eine MMC / SDv1.x
7.2 Ansonsten SDv2 oder SDHC
8. CMD58 senden bei korrekter antwort haben wa dann ein SDHC
9. ACMD41 mit gesetztm SDHC bit senden (benötigen MMCs nicht CMD1?) bist 
karte gesetzt oder timeout abgelaufen is
9.1 Wenn Karte auf 0 wechselt ist sie initialisiert und SDHC karten 
geben dauerhaft 0xFF aus (stimmt das?).
--> Karte ist initialisiert.
10. Speed hochsetzten
11. Chipselect auf high
12. ein paar dummy signale (0xFF) zum clearen senden


is was an der Reihenfolge falsch oder muss ich was beachten?

von Namehiereingeben (Gast)


Lesenswert?

Flo W. schrieb:
> 7. CMD8 mit CRC (wie lautet die) und gesetztem HCS bit (heisst bit 30
> das 30.bit von den argumenten her oder vom gesamten command?)

Es ist Bit 30 des 32-Bit-Arguments nach dem Kommandobyte. Wenn du als 
Parameter 0x1aa sendet ist die passende CRC 0x87.

> 7.1 Bei Fehler ist es eine MMC / SDv1.x
> 7.2 Ansonsten SDv2 oder SDHC

Stimmt so

> 8. CMD58 senden bei korrekter antwort haben wa dann ein SDHC

Wenn Bit 30 in der Antwort gesetzt ist - es kann auch eine 
Nicht-SDHC-2.x-SD-Karte sein

> 9. ACMD41 mit gesetztm SDHC bit senden (benötigen MMCs nicht CMD1?) bist
> karte gesetzt oder timeout abgelaufen is

Ja - die meisten MMC-Karten sagen schon nach CMD55 "kenne ich nicht", 
hier liegt aber eine Sandisk-Karte die erst beim Absetzen des 
darauffolgenden (A)CMD41 mit einem Fehler aussteigt - in beiden Fällen 
initialisiert man einfach mit CMD1 statt ACMD41. Wenn man den Code 
einfach halten möchte kann man das CMD1 auch problemlos an eine SD-Karte 
senden, die sollte dann schon beim ersten mal "ok, bin initialisiert" 
zurückmelden.

> 9.1 Wenn Karte auf 0 wechselt ist sie initialisiert und SDHC karten
> geben dauerhaft 0xFF aus (stimmt das?).

Korrekt initialisierte SDHC-Karten geben dann auch 0 aus.

(SDXC-Karten sind mir noch zu teuer, scheinen aber nach kurzem 
Überfliegen der Specs genauso initialisiert zu werden)

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

argh, hab grad die 0x87 als crc selber berechnet per hand aufm papier 
:P. Hat ewig gedauert ^^.

aber danke shconma für die Antwort hilft mir weiter.

Also eins finde ich aber komisch

laut Spezifikation habe ich ja bei 0x05 response eine MMC oder SDCv1

nun habe ich hier vor mir nur 2 microSD Karten liegen. Eine mit 256mb wo 
ich mir dachte das is bestimmt eine sd karte der version eins

und iene mit 4gb also SDCH

bei der 256mb bekomme ich R1:0x01 und restdaten: 001AAF als antwort 
zurück
(ist somit also V2)

bei der 4gb bekomme ich R1:0x05 und restdaten: FFFFFF als antwort zurück
also kann meine 4GB karte das Command nicht oder wie? sollte sie doch 
eigtl.

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Also Hier mal meine init methode
ich habe die command namen etwas geändert
1
uint8_t sd_init(){
2
  spi_speed_low();
3
  
4
  sd_hw_init();
5
  
6
    sd_low(); 
7
    
8
    uint8_t rec = 0; //temporary variable to save responses
9
    
10
    //CMD0 to Reset Card
11
    rec = sd_send_cmd( SD_GO_IDLE_STATE, 0, 0x94 ); //rec = 0x5 when Card is a SDHC-Card
12
    
13
    
14
  if(rec){
15
    //CMD8 with param 000001AA to identify SDHC Card
16
    rec = sd_send_cmd( SD_SEND_IF_COND, (0x000001AA | 1L<<30), 0x86); 
17
    printf("%X", spi_send_byte(0xFF));
18
    printf("%X", spi_send_byte(0xFF));
19
    printf("%X", spi_send_byte(0xFF));
20
    printf("%X", spi_send_byte(0xFF));
21
    
22
  }else{
23
    return SD_UNKNOWN_CARD;
24
  }
25
  return SD_UNKNOWN_CARD;
26
}

ich setze hier das HCS aber dann kommt mit der crc wieder nen fehler ... 
gibs nicht irgendwo einen rechner dafür unter google find ich keinen.

achja ich schreibe 86 rein weil ich das letzte bit noch in meiner 
methode setzte.

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Mah ich bin am verzweifeln was die HC karten angeht.
Die 256MB karte von mir kann ich ohne probs initialisieren aber die 4GB 
karte will net.

Aber ich sehe auuch gerade dass da ein CRC error kommt, ich dachte eigtl 
dass bei dem ACMD41 die CRC net berücksichtig wird.

also hier der momentane code:

sd.h
1
#ifndef __SDCARD__
2
#define __SDCARD__
3
4
/* Includes */
5
#include "../uart/uart.h"
6
#include "../spi/spi.h"
7
8
#ifndef DEBUG
9
  #define DEBUG //Should be only defined if Debug messages are needed
10
#endif
11
/*spi methods*/
12
#define spi_send_byte(x)   spi2_transmit(x)  //Method to transmit a Byte via SPI
13
#define spi_speed_low()   ;                   //sets SPI Clockrate between 100kHz and 400kHz
14
#define spi_speed_high()   ;           //sets SPI Clockrate to maximum
15
16
/*defines for Hardware Initialisation*/
17
#define SD_CS_PIN        PC6    //Chipselect for SD Card
18
#define SD_CS_PORT       PORTC  //Port of SD_CS
19
#define SD_CS_DDR        DDRC   //Data Direction Register for SD_CS
20
21
#define sd_low()         SD_CS_PORT &= ~(1 << SD_CS_PIN) // SD_CS -> '1'
22
#define sd_high()        SD_CS_PORT |= (1 << SD_CS_PIN)  // SD_CS -> '0'
23
24
/*some other defines:*/
25
#define SD_INIT_TIMEOUT   20  //value between 0 and 254 
26
#define SD_HCS            1   // 0 = SDHC disable, 1 = SDHC enable
27
28
29
/*SD Card Types*/
30
#define SD_UNSUPPORTED    0 
31
#define SD_SDCV1       1 
32
#define SD_SDCV2       2 
33
#define SD_MMC         3 
34
#define SD_HC        4 
35
36
/* 
37
Command defines:
38
39
Command Format (6 Bytes): 
40
start bit ('0') + transmission bit('1') + command index (6bit) + arguments (4 byte) + CRC7 (7bit)+ end bit('1')
41
*/
42
43
/*SPI specifik commands (start bit+transmission bit+command index):*/   
44
#define SD_GO_IDLE_STATE        0x00 //CMD0
45
#define SD_SEND_OP_COND        0x01 //CMD1
46
#define SD_SWITCH_FUNC        0x06 //CMD6
47
#define SD_SEND_IF_COND        0x08 //CMD8
48
#define SD_SEND_CSD         0x09 //CMD9
49
#define SD_SEND CID         0x0A //CMD10
50
#define SD_STOP_TRANSMISSION     0x0C //CMD12
51
#define SD_SEND_STATUS         0x0D //CMD13
52
#define SD_SET_BLOCKLEN       0x10 //CMD16
53
#define SD_READ_SINGLE_BLOCK     0x11 //CMD17
54
#define SD_READ_MULTIPLE_BLOCK     0x12 //CMD18
55
#define SD_WRITE_BLOCK         0x18 //CMD24
56
#define SD_WRITE_MULTIPLE_BLOCK    0x19 //CMD25
57
#define SD_PROGRAM_CSD         0x1B //CMD27
58
#define SD_SET_WRITE_PROT        0x1C //CMD28
59
#define SD_CLR_WRITE_PROT       0x1D //CMD29
60
#define SD_SEND_WRITE_PROT       0x1E //CMD30
61
#define SD_ERASE_WR_BLK_START_ADDR   0x20 //CMD32
62
#define SD_ERASE_WR_BLK_END_ADDR   0x21 //CMD33
63
#define SD_ERASE          0x26 //CMD38
64
#define SD_LOCK_UNLOCK         0x2A //CMD42
65
#define SD_APP_CMD           0x37 //CMD55
66
#define SD_GEN_CMD           0x38 //CMD56
67
#define SD_READ_OCR         0x3A //CMD58
68
#define SD_CRC_ON_OFF         0x3B //CMD59
69
70
#define SD_A_SEND_OP_COND      0x29 //ACMD41
71
72
#define SD_CMD_MASK         0x40; //star bit and transmission bit
73
74
/* command responses */
75
/* Format R1 (1 byte)*/
76
#define SD_R1_IDLE_STATE       1
77
#define SD_R1_ERASE_RESET        2
78
#define SD_R1_ILLEGAL_COMMAND     3
79
#define SD_R1_COM_CRC_ERR       4
80
#define SD_R1_ERASE_SEQ_ERR     5
81
#define SD_R1_ADDRESS_ERR      6
82
#define SD_R1_PARAMETER_ERR     7
83
84
/* Format R3 (5 bytes)*/
85
#define SD_R3_IDLE_STATE       33
86
#define SD_R3_ERASE_RESET       34
87
#define SD_R3_ILLEGAL_COMMAND     35
88
#define SD_R3_COM_CRC_ERR       36
89
#define SD_R3_ERASE_SEQ_ERR     37
90
#define SD_R3_ADDRESS_ERR       38
91
#define SD_R3_PARAM_ERR       39
92
93
/*Methods*/
94
95
//initialize SD Card 
96
uint8_t sd_init(void); 
97
98
//initialize hardware of SD Card after Power on   
99
void sd_hw_init(void); 
100
101
//Sends a 6 Byte long command via SPI
102
uint8_t sd_send_cmd(uint8_t, uint32_t, uint8_t); 
103
104
//Reads the next 4 Bytes after a command with R3 response
105
uint32_t sd_read_ocr(void);
106
107
#endif
----------------------------------------------------------

sd.c
1
#include "sd.h"
2
#include <util/delay.h>
3
4
// Method to initialize SDCard/MMC after Powerup
5
// name: sd_init()
6
// @param
7
// @return returns type of inserted Card
8
9
uint8_t sd_init(){
10
  
11
  spi_speed_low(); //set Speed to max 400kHz
12
  sd_hw_init();    //Initialize Hardware
13
    sd_low();      //SD_CS -> 0
14
15
  #ifdef DEBUG
16
    printf("Go IDLE mode ... \n");
17
  #endif
18
  
19
    //CMD0 to reach IDLE State
20
    uint8_t rec = sd_send_cmd( SD_GO_IDLE_STATE, 0, 0x95 ); //CMD0
21
    
22
  if(rec == 0){
23
    #ifdef DEBUG
24
      printf("Maybe no Cardinserted \n");
25
    #endif
26
    return SD_UNSUPPORTED;
27
  }else{
28
    #ifdef DEBUG
29
      printf("Card is in IDLE mode\n");
30
    #endif
31
  }
32
33
  #ifdef DEBUG
34
    printf("Identify Card Specifikation ... \n");
35
  #endif
36
  
37
  /* identify SD type */
38
  uint8_t type = SD_UNSUPPORTED;
39
  
40
  rec = sd_send_cmd(SD_SEND_IF_COND, 0x1AA, 0x87); //CMD8
41
  
42
  if(rec == (0x1|(1<<SD_R1_ILLEGAL_COMMAND))){ //0x05
43
    type = SD_MMC;//SDC V1 or MMC
44
    #ifdef DEBUG
45
      printf("MMC or SDC V1 detected\n");
46
    #endif
47
  }
48
  if(rec){ //0x01
49
    uint32_t ocr = sd_read_ocr();
50
    if((ocr&0x00000FFF)==0x1AA){
51
      type = SD_SDCV2;//SDC V2
52
      #ifdef DEBUG
53
        printf("SDC V2 detected\n");
54
      #endif
55
    }
56
  }
57
  
58
  #ifdef DEBUG
59
    printf("leave idle mode\n");
60
  #endif
61
  int count = SD_INIT_TIMEOUT;
62
  rec = 1;
63
  while(rec){
64
    sd_send_cmd(SD_APP_CMD, 0, 0xFF); //CMD55
65
    rec = sd_send_cmd(SD_A_SEND_OP_COND, 0, 0xFF);//ACMD41
66
    if(!(--count)|!rec)
67
      break;
68
  }
69
  
70
  count = SD_INIT_TIMEOUT;
71
  while(rec){ //CMD1
72
    rec = sd_send_cmd(SD_SEND_OP_COND, 0, 0xFF);
73
    if(!(--count)|!rec)
74
      break;
75
  }
76
  
77
  #ifdef DEBUG
78
    if(!rec)
79
      printf("Karte initialisiert\n");
80
  #endif
81
  
82
  return type;
83
}  
84
85
// Initialize Hardware after Poweron 
86
// 1. SD_CS -> output and 1
87
// 2. Wait 1 ms
88
// 3. 74+ dummy clocks
89
//
90
// name: sd_hw_init
91
// @param
92
// @return
93
94
void sd_hw_init(void){
95
  /*Chips select for SDCard to output*/
96
    SD_CS_DDR |= ( 1 << SD_CS_PIN );  
97
    /*CS to logic 1*/
98
    sd_high();
99
  /*wait 1 ms*/
100
  _delay_ms(1);
101
    //send 74+ dummy clocks
102
    for(int i = 0; i<8 ; i++)
103
        spi_send_byte(0xFF);
104
  
105
#ifdef DEBUG
106
    printf("SDCard Hardware initialized.\n");
107
#endif
108
}
109
110
// Sends a command to SDC via SPI and returns R1
111
// name: sd_hw_init
112
// @param cmd command for SD Card
113
// @param arg Arguments for the CMD
114
// @param crc checksum
115
// @return command response in R1 format
116
117
uint8_t sd_send_cmd(uint8_t cmd, uint32_t arg, uint8_t crc){
118
  /*build complete Command*/
119
  uint8_t buffer[6] ;                   //temporary Buffer for the CMD
120
  buffer[0] = cmd | SD_CMD_MASK;        //Set start and transmission bit + Command
121
  buffer[1] = (arg & 0xFF000000) >> 24; //Set parameter byte 1
122
  buffer[2] = (arg & 0x00FF0000) >> 16; //Set parameter byte 2 
123
  buffer[3] = (arg & 0x0000FF00) >> 8;  //Set parameter byte 3
124
  buffer[4] = (arg & 0x000000FF);       //Set parameter byte 4
125
  buffer[5] = crc | 0x01;               //CRC + Endbit '1'
126
127
  #ifdef DEBUG
128
    //Prints the Command
129
    printf("Sending CMD: ");
130
    printf("%d, ", buffer[0]&0b00111111);
131
    printf("ARGS: ");
132
    for(uint8_t i=1; i<6; i++)
133
      printf("0x%x, ", buffer[i]);
134
  #endif
135
  
136
  //Send complete Command via SPI
137
    for(uint8_t i=0; i<6; i++)
138
        spi_send_byte(buffer[i]); 
139
  
140
  //Send dummy-byte (cause Card needs time for respond)
141
  spi_send_byte(0xFF); 
142
  
143
  uint8_t ret = spi_send_byte(0xFF);
144
  
145
  #ifdef DEBUG
146
    //Prints the Command
147
    printf("recv.: 0x%x", ret);
148
    printf(".\n");
149
  #endif  
150
  //receive byte and return
151
    return ret;
152
}
153
154
uint32_t sd_read_ocr(){
155
  uint32_t ocr = (uint32_t)spi_send_byte(0xFF)<<24;
156
  ocr |= (uint32_t)spi_send_byte(0xFF)<<16;
157
  ocr |= (uint32_t)spi_send_byte(0xFF)<<8;
158
  return (ocr |= spi_send_byte(0xFF));
159
}

-----------------------------------------------------

und auf der Konsole erscheint bei der 256MB Karte:

UART Initialized
USART as SPI Initialized
Welcome to WeSa System v0.0.1a
Starting SD initialsation.

SDCard Hardware initialized.

Go IDLE mode ...
Sending CMD: 0, ARGS: 0x0, 0x0, 0x0, 0x0, 0x95, recv.: 0x1.
Card is in IDLE mode

Identify Card Specifikation ...
Sending CMD: 8, ARGS: 0x0, 0x0, 0x1, 0xaa, 0x87, recv.: 0x1.
SDC V2 detected
leave idle mode
Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0x1.
Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0x0.
Karte initialisiert

--------------------------------------------------------------

und bei der 4GB


UART Initialized
USART as SPI Initialized
Welcome to WeSa System v0.0.1a
Starting SD initialsation.

SDCard Hardware initialized.
Go IDLE mode ...
Sending CMD: 0, ARGS: 0x0, 0x0, 0x0, 0x0, 0x95, recv.: 0x1.
Card is in IDLE mode
Identify Card Specifikation ...
Sending CMD: 8, ARGS: 0x0, 0x0, 0x1, 0xaa, 0x87, recv.: 0x5.
leave idle mode
Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0x9.

Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 55, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 41, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

//.. bis der Timeout greift .. danach kommt dann

Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.
Sending CMD: 1, ARGS: 0x0, 0x0, 0x0, 0x0, 0xff, recv.: 0xff.

//wieder bis der Timeout greift

---------------------------------------------------------------

die 9 bedeutet ja ich habe einen crc fehler ...
und ich weiss immernoch nicht genau wie und wo ich das HCS setzten soll, 
weil sich ja dann die CRC ändert.


vlt weiss ja einer wie ich das in meinem Code richtig mache.

die überprüfung auf HC mittels cmd58 hab ich ersma rausgenommen, weil 
sollte ja trotzdem fluppen. mit dem ACMD41

von C.Fischer (Gast)


Lesenswert?

Funktioniert es nun bei dir?

Gruss !

von Christian F. (christianf)


Lesenswert?

im Übrigend musst du nach erfolgreichem CMD8 response ACMD41 mit 
folgendem Argument schicken :

0x40000000 d.h. die Karte ist ab Spezifikation 2.0 und unterstützt evtl. 
das HCS bit.

Siehe Flow:

http://elm-chan.org/docs/mmc/sdinit.png

Gruss

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.