Koppla SD-kort till AVR, får det inte att funka *Löst*

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Koppla SD-kort till AVR, får det inte att funka *Löst*

Inlägg av gunne »

Jag försöker koppla ett SD-kort till en atmega128 men får det inte att funka. Jag använder mig av AVRlib som har en MMC/SD-modul och koden till den finns här. Bra info om MMC/SD finns bland annat här.

Jag har kopplat in kortet enligt detta schema fast till en AVR då.

När jag ska initiera kortet så skickar jag först CMD0 (GO_IDLE_STATE) och får tillbaks 0x01 vilket skall betyda att kortet har gått in i "idle state" vilket den ska. Då verkar ju SPI-biten funka som den ska.

Sen försöker jag skicka CMD1 (SEND_OP_COND) för att initiera kortet. När jag gör detta (100ggr för att vänta på resultat) så ska jag få tillbaks 0x00 vilket betyder att kortet gått in i "SPI-mode". Dock får jag tillbaks 0x05 vilket jag tror betyder "Illegal command". Inte bra.

Jag har testat att sänka frekvensen, kolla med oscilloskop att signalerna kommer fram, provat tre olika SD-kort (2st 1GB och 1 512MB) och sedvanligt allmänt testande fram och tillbaka.

Kan det vara så att korten jag har är SD v2 (enligt länken ovan: "How to support SDC Ver2 and high capacity cards")? I såna fall skall jag enligt samma länk skicka "CMD8 with 0x1AA and correct CRC" innan jag initialiserar. Hur får jag reda på vad rätt CRC är?

Tror ni att det är detta som är felet? Vad mer kan jag titta på i felsökningen? Någon annan som lyckats koppla ett stort (512MB+) SD till en uC?
Senast redigerad av gunne 1 oktober 2008, 23:33:26, redigerad totalt 1 gång.
Nerre
Inlägg: 27257
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Inlägg av Nerre »

0x01 behöver ju inte vara en korrekt svarskod, det är ju en bit hög och övriga låga och det kan man ju få även vid fel.

CRC får du väl räkna fram antar jag.

0x05 är ju Idle state och Command CRC error enligt den där sidan du länkade till.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

0x05 blir väl 00000101b => "In idle state" och "illegal command" enligt sidan ovan?

Jo, jag skulle vilja räkna fram CRC, men hur vet man vilken algoritm de använder? Det finns väl flera sätt? Har testat lite med denna utan resultat. Jag vet ju att CMD0 skall ge CRC 0x95 men får inte till det.

Edit: Här hittade jag lite mer information om SD och dess CRC. Och här finns lite exempel på hur man räknar ut CRC-7.
Senast redigerad av gunne 29 september 2008, 15:59:47, redigerad totalt 2 gånger.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Kortet använder CRC-7 för kommandon. Googla på detta så hittar Du en del.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

SD kort har INTE CRC då de körs i rent seriellt läge
Kör du 4 data så används CRCn.
Första kommandot du skickar som sätter seriellt mode stänger
även av CRC
Sparkade igång ett sdkort med atmel i somras... så vet av
erfarenhet.

Kika på denna hemsida, finns mycket bra om SD kort där
http://www.ulrichradig.de

Swech
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

Jag har gått igenom diverse kodexempel och alla ser väldigt likadana ut. En skillnad i koden som du länkade till Swech är att han skickar 8 klockcykler innan varje kommando medan de flesta endast gör det innan första kommandot.

Kod: Markera allt

unsigned char mmc_write_command (unsigned char *cmd) {
       ...
	//set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) 
	MMC_Disable();
	//sendet 8 Clock Impulse
	mmc_write_byte(0xFF);
	//set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
	MMC_Enable();
...
Har inte hårdvaran här nu men jag ska testa det imorgon.

Jag har testat att skicka diverse andra kommandon efter CMD0 men jag får alltid tillbaka 0x05. Testade även att köra allting på 3,3V för att eliminera eventuella problem med spänningsdelningen utan resultat.

Swech, vad var det för kort du testade? Alla exempel jag har hittat är testade med typ 32MB-, 64MB- eller 128MB-kort och jag har ju som sagt större kort.
Användarvisningsbild
strombom
Inlägg: 3305
Blev medlem: 27 maj 2003, 10:50:20
Ort: Västra Götaland
Kontakt:

Inlägg av strombom »

Jag skrev för ett tag sedan en vhdl-modul för att styra ett sd-kort...

här är lite kod för reset-sekvensen:
http://rafb.net/p/qeFKkR18.html
om den är svår att följa är det bara att säga till så försöker jag förklara...

jag skickar ett kommando i varje state
sd kommandot skickas i cmd_num och data i cmd_arg
svaret från kortet kommer ett state senare i cmd_response

glöm inte heller att kortet måste ha minst 72 (har jag för mig) klockcykler innan man kan börja prata med det och minst 8 klockcykler efter varje slutfört kommando

tänk sedan på att du adresserar ett SDHC kort (kort som är 4GB eller större) i sektorer och inte bytes.

edit: såg nu att det var gammal kod där jag inte har använt sd v1 kort, men det gör väl inget :)

edit2: nu såg jag att du körde med 512MB och 1GB kort, de är inte SDHC så du behöver inte oroa dig över något sådant...

edit3: :)
Du hade skrivit om det här med klockcykler före/efter kommando, så här säger specen:

Kod: Markera allt

It is an obvious requirement that the clock shall be running for the card to output data or
response tokens. After the last SD Memory Card bus transaction, the host is required, to provide
8 (eight) clock cycles for the card to complete the operation before shutting down the clock. Fol-
lowing is a list of the various bus transactions:
  •A command with no response. 8 clocks after the host command end bit.
  •A command with response. 8 clocks after the card response end bit.
  •A read data transaction. 8 clocks after the end bit of the last data block.
  •A write data transaction. 8 clocks after the CRC status token.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

det är ett 128Mb kort jag kör med
Kör med resistor späningsdelare

Swech
Nerre
Inlägg: 27257
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Inlägg av Nerre »

Vanlig spänningsdelare för att få matningen till kortet??

Drar inte kortet lite för mycket ström för att det skall funka bra?

Jag vill minnas att kort brukar bli ganska varma när de används, det tyder på att de drar rätt bra med ström.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

Nej, matningen till kortet var 5V och sen två-tre dioder emellan. Men sen drog jag ju ner hela processorn och allt (STK500) till 3,3V för att eliminera den felkällan.

Jag fick till initieringen och läsning av kortet igår. Det var som misstänktes tidigare att man måste rensa med åtta klockcykler efter varje kommando. Dock har jag inte lyckats skriva till kortet än av nån anledning. Samt att bara ett av tre kort funkar (kingston 1GB). Ska testa med ytteligare ett kort idag.

Jag kan återkomma med lite kod om några timmar.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

Nu blir det ett långt inlägg det här... Eller mycket kod.

Jag har ändrat i mmc.c så att den ser ut så här nu:

Kod: Markera allt

#include <avr/io.h>			// include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h>	// include interrupt support

#include "global.h"		// include our global settings
#include "spi.h"		// include spi bus support
#include "rprintf.h"
#include "mmc.h"
#include "mmcconf.h"

// Functions
void mmcInit(void) {
	// initialize SPI interface
	spiInit();
	// release chip select
	sbi(MMC_CS_DDR, MMC_CS_PIN);
	sbi(MMC_CS_PORT,MMC_CS_PIN);
}

u08 mmcReset(void) {
	u08 i, r1=0;
	u16 retry=0;

	do {
		// send dummy bytes with CS high before accessing
		for(i=0;i<10;i++) spiTransferByte(0xFF);
		// resetting card, go to SPI mode
		r1 = mmcCommand(MMC_GO_IDLE_STATE, 0);	//
		#ifdef MMC_DEBUG
		rprintf("MMC_GO_IDLE_STATE: R1=0x%x\r\n", r1);
		#endif

		retry++;
		if(retry>100) return -1;
	} while(r1 != 0x01);

	// TODO: check card parameters for voltage compliance
	// before issuing initialize command

	retry = 0;
	do
	{
		// initializing card for operation
		r1 = mmcCommand(MMC_SEND_OP_COND, 0);
		// Release chip
		sbi(MMC_CS_PORT,MMC_CS_PIN);	// Doesn't work without this, dunno why
		#ifdef MMC_DEBUG
		rprintf("%d MMC_SEND_OP_COND: R1=0x%x\r\n", retry, r1); 
		#endif
		
		retry++;
		if(retry>10000) return -1;
	} while(r1);
	
		
	// turn off CRC checking to simplify communication
	r1 = mmcCommand(MMC_CRC_ON_OFF, 0);
	#ifdef MMC_DEBUG
	rprintf("MMC_CRC_ON_OFF: R1=0x%x\r\n", r1);
	#endif

	// set block length to 512 bytes
	r1 = mmcCommand(MMC_SET_BLOCKLEN, 512);
	#ifdef MMC_DEBUG
	rprintf("MMC_SET_BLOCKLEN: R1=0x%x\r\n", r1);
	#endif

	// return success
	return 0;
}

u08 mmcRead(u32 sector, u08* buffer) {
	u08 r1;
	u16 i;

	// assert chip select
	cbi(MMC_CS_PORT,MMC_CS_PIN);
	// issue command
	r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9);
	#ifdef MMC_DEBUG
	rprintf("MMC Read Block R1=0x%x\r\n", r1);
	#endif
	// check for valid response
	if(r1 != 0x00)
		return r1;
	// wait for block start
	while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ);
	// read in data
	for(i=0; i<0x200; i++)
	{
		*buffer++ = spiTransferByte(0xFF);
	}
	// read 16-bit CRC
	spiTransferByte(0xFF);
	spiTransferByte(0xFF);
	// release chip select
	sbi(MMC_CS_PORT,MMC_CS_PIN);
	// return success
	return 0;
}

u08 mmcWrite(u32 sector, u08* buffer)
{
	u08 r1;
	u16 i;

	// assert chip select
	cbi(MMC_CS_PORT,MMC_CS_PIN);

	// issue command
	r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9);
	#ifdef MMC_DEBUG
	rprintf("MMC Write Block R1=0x%x\r\n", r1);
	#endif
	// check for valid response
	if(r1 != 0x00)
		return r1;
	// send dummy
	spiTransferByte(0xFF);
	// send data start token
	spiTransferByte(MMC_STARTBLOCK_WRITE);
	// write data
	for(i=0; i<0x200; i++)
	{
		spiTransferByte(*buffer++);
	}
	// write 16-bit CRC (dummy values)
	spiTransferByte(0xFF);
	spiTransferByte(0xFF);
	// read data response token
	r1 = spiTransferByte(0xFF);
	if((r1&MMC_DR_MASK) != MMC_DR_ACCEPT)
		return r1;
	#ifdef MMC_DEBUG
	rprintf("Data Response Token=0x%x\r\n", (r1&MMC_DR_MASK));
	#endif
	// wait until card not busy
	while(!spiTransferByte(0xFF));
	// release chip select
	sbi(MMC_CS_PORT,MMC_CS_PIN);
	// return success
	return 0;
}

u08 mmcCommand(u08 cmd, u32 arg)
{
	u08 r1;
	u08 retry=0;
	u08 i;

	// assert chip select
	cbi(MMC_CS_PORT,MMC_CS_PIN);

	// send command
	spiTransferByte(cmd | 0x40);
	spiTransferByte(arg>>24);
	spiTransferByte(arg>>16);
	spiTransferByte(arg>>8);
	spiTransferByte(arg);
	spiTransferByte(0x95);	// crc valid only for MMC_GO_IDLE_STATE
	// end command

	// wait for response
	// if more than 8 retries, card has timed-out
	// return the received 0xFF
	while((r1 = spiTransferByte(0xFF)) == 0xFF)
		if(retry++ > 8) break;

	// Flush buffer after accessing
	sbi(MMC_CS_PORT,MMC_CS_PIN);
	spiTransferByte(0xFF);
	cbi(MMC_CS_PORT,MMC_CS_PIN);

	// return response
	return r1;
}

Det jag ändrade för att få det att fungera över huvud taget var att jag la till "Flush buffer after accessing"-biten i mmcCommand i slutet.

Som sagt funkar det fortfarande sådär och jag vet inte varför. Jag har testat på fyra kort nu. De två som funkar bäst är båda kingston på 1 resp 2 GB. De initieras efter ungefär 25-30 CMD1 (SEND_OP_COND). Ett CubeMemory 512MB initieras efter typ 1000-3000 (!) skickningar av CMD1. Ett Maxell 1GB initieras inte alls.

Kingston 1GB funkar bäst så det labbar jag med. Jag kan läsa från det med mmcRead. Det har jag verifierat genom att lägga en stor textfil på kortet och jag får samma text vid läsning. Att skriva fungerar dock inte av nån anledning.

Nedan är en utskrift från mitt program:

Kod: Markera allt

> Initiating USB...Done.
> Initiating SPI...Done.
> Initiating LCD...Done.
> Initiating Timer...Done.
> Initiating SD-card...MMC_GO_IDLE_STATE: R1=0x0001
0 MMC_SEND_OP_COND: R1=0x0001
1 MMC_SEND_OP_COND: R1=0x00F0
2 MMC_SEND_OP_COND: R1=0x0001
3 MMC_SEND_OP_COND: R1=0x0001
4 MMC_SEND_OP_COND: R1=0x00FC
5 MMC_SEND_OP_COND: R1=0x00FC
6 MMC_SEND_OP_COND: R1=0x00F8
7 MMC_SEND_OP_COND: R1=0x00F8
8 MMC_SEND_OP_COND: R1=0x00FE
9 MMC_SEND_OP_COND: R1=0x00FC
10 MMC_SEND_OP_COND: R1=0x00F8
11 MMC_SEND_OP_COND: R1=0x00FE
12 MMC_SEND_OP_COND: R1=0x00F8
13 MMC_SEND_OP_COND: R1=0x00F8
14 MMC_SEND_OP_COND: R1=0x00F0
15 MMC_SEND_OP_COND: R1=0x00F8
16 MMC_SEND_OP_COND: R1=0x00F8
17 MMC_SEND_OP_COND: R1=0x00F8
18 MMC_SEND_OP_COND: R1=0x00FC
19 MMC_SEND_OP_COND: R1=0x00FC
20 MMC_SEND_OP_COND: R1=0x00FC
21 MMC_SEND_OP_COND: R1=0x00FC
22 MMC_SEND_OP_COND: R1=0x00F0
23 MMC_SEND_OP_COND: R1=0x0001
24 MMC_SEND_OP_COND: R1=0x00FC
25 MMC_SEND_OP_COND: R1=0x0000
MMC_CRC_ON_OFF: R1=0x0000
MMC_SET_BLOCKLEN: R1=0x0000
Done

Buffer to write:
     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF
     -----------------------------------------------  ---- ASCII -----
0000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  ................
0010 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F  ................
0020 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F   !"#$%&'()*+,-./
0030 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F  0123456789:;<=>?
0040 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F  @ABCDEFGHIJKLMNO
0050 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F  PQRSTUVWXYZ[\]^_
0060 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F  `abcdefghijklmno
0070 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F  pqrstuvwxyz{|}~
0080 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F  €‚ƒ„…†‡ˆ‰Š‹ŒŽ
0090 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F  ‘’“”•–—˜™š›œžŸ
00A0 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF   ¡¢£¤¥¦§¨©ª«¬­®¯
00B0 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF  °±²³´µ¶·¸¹º»¼½¾¿
00C0 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
00D0 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF  ÐÑÒÓÔÕÖרÙÚÛÜÝÞß
00E0 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF  àáâãäåæçèéêëìíîï
00F0 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF  ðñòóôõö÷øùúûüýþÿ
0100 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  ................
0110 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F  ................
0120 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F   !"#$%&'()*+,-./
0130 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F  0123456789:;<=>?
0140 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F  @ABCDEFGHIJKLMNO
0150 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F  PQRSTUVWXYZ[\]^_
0160 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F  `abcdefghijklmno
0170 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F  pqrstuvwxyz{|}~
0180 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F  €‚ƒ„…†‡ˆ‰Š‹ŒŽ
0190 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F  ‘’“”•–—˜™š›œžŸ
01A0 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF   ¡¢£¤¥¦§¨©ª«¬­®¯
01B0 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF  °±²³´µ¶·¸¹º»¼½¾¿
01C0 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
01D0 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF  ÐÑÒÓÔÕÖרÙÚÛÜÝÞß
01E0 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF  àáâãäåæçèéêëìíîï
01F0 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF  ðñòóôõö÷øùúûüýþÿ

MMC Write Block R1=0x0000
Data Response Token=0x0005

MMC Read Block R1=0x0000

Reading sector 3000:
     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF
     -----------------------------------------------  ---- ASCII -----
0000 47 21 17 E0 62 1F 00 4E 53 C3 60 24 7C 24 72 D0  G!.àb..NSÃ`$|$rÐ
0010 B8 84 A1 34 9F 11 F1 3B 61 4E AF 27 54 37 06 AD  ¸„¡4Ÿ.ñ;aN¯'T7.­
0020 94 7B B1 67 8C 91 4D DC 49 14 B0 CA 6D 3B 2A 48  ”{±gŒ‘MÜI.°Êm;*H
0030 C1 19 12 CA 51 03 41 C9 FF 11 9E 67 17 DA 85 11  Á..ÊQ.AÉÿ.žg.څ.
0040 66 9B 51 03 7A 5E F6 AA 81 97 FC 38 F7 27 17 23  f›Q.z^öª—ü8÷'.#
0050 E9 D7 CE 00 D3 41 D5 F7 CE 99 2E C5 0F 14 97 15  é×Î.ÓAÕ÷Ι.Å..—.
0060 0A FB 8B 13 1F E7 1C 7B 62 72 14 8E 3E 69 45 F3  .û‹..ç.{br.Ž>iEó
0070 EE 42 97 F7 AB AD EA C6 3D 9F 79 D9 6A 0D E0 FF  îB—÷«­êÆ=ŸyÙj.àÿ
0080 BC EE 97 4F 85 2A 17 C1 85 66 57 57 4D 79 D6 25  ¼î—O…*.Á…fWWMyÖ%
0090 A3 57 A2 FD 6E 4D 20 75 69 B1 13 92 EC 1D 81 C4  £W¢ýnM ui±.’ì.Ä
00A0 ED 4D 9F EC 06 13 3E 67 A7 83 D6 5F 6C A6 08 0B  íMŸì..>g§ƒÖ_l¦..
00B0 90 DF A6 60 92 3B 97 F8 B6 18 FE 5C E1 91 C8 6C  ß¦`’;—ø¶.þ\á‘Èl
00C0 86 08 B4 4D 57 9D DB A1 59 5E B0 B0 DF B2 77 2F  †.´MWÛ¡Y^°°ß²w/
00D0 67 3A 09 49 3B A8 56 2F 79 EF 0A 7E 86 B7 63 09  g:.I;¨V/yï.~†·c.
00E0 DD 03 E2 2A CB 77 CC 8D 58 04 A0 86 2D 97 11 99  Ý.â*Ëw̍X. †-—.™
00F0 8B AD 19 28 0C 47 D9 A5 8B 58 F3 00 0B 55 78 F8  ‹­.(.GÙ¥‹Xó..Uxø
0100 0B 5E F2 D2 E7 1B 1E 3A B2 87 59 F2 F7 2B CD 07  .^òÒç..:²‡Yò÷+Í.
0110 97 3D 15 00 5A 9A 61 B4 95 38 51 E9 AC E7 B4 62  —=..Zša´•8Qé¬ç´b
0120 48 F5 40 71 2A 7F F1 4A 85 73 53 32 42 09 73 94  Hõ@q*ñJ…sS2B.s”
0130 04 56 4E DD 4A 51 A0 9A BF E3 AA 78 31 67 4E 9E  .VNÝJQ š¿ãªx1gNž
0140 46 7D 9B CE 1B 12 64 13 7C E1 2E 2C 56 6F EF 4B  F}›Î..d.|á.,VoïK
0150 DA D2 29 7F 4F CB 86 BB 9B 77 1F B3 26 C3 C3 8C  ÚÒ)Oˆ»›w.³&ÃÌ
0160 79 BB 5E 60 6F 41 99 B8 44 01 73 2E 51 ED F7 ED  y»^`oA™¸D.s.Qí÷í
0170 54 39 62 0B A6 A9 A6 91 AD C3 04 A9 A3 DD 89 20  T9b.¦©¦‘­Ã.©£Ý‰
0180 62 A4 B1 44 FA EA 26 94 BF 97 51 6F 58 4E 95 3B  b¤±Dúê&”¿—QoXN•;
0190 CB 56 ED D3 75 64 A2 B5 F3 AB FC 1C 12 25 B0 B8  ËVíÓud¢µó«ü..%°¸
01A0 ED AA 96 BF B3 A3 E9 40 B0 ED 33 D9 E9 0D B9 73  íª–¿³£é@°í3Ùé.¹s
01B0 95 C2 6A 8A 41 85 BF CA 13 8B 8C 03 9B 5F 12 F1  •ÂjŠA…¿Ê.‹Œ.›_.ñ
01C0 C7 89 9A C3 A9 66 F9 95 FD 8E 70 A2 BC 39 29 6E  ljšÃ©fù•ýŽp¢¼9)n
01D0 DD 48 F8 8E 74 1E B2 24 60 98 2B 07 DC 74 1B 0C  ÝHøŽt.²$`˜+.Üt..
01E0 51 6A 7F 17 9B A0 8D B5 8E 52 93 FF 9B 77 89 43  Qj.› µŽR“ ›w‰C
01F0 77 B9 91 BF B0 DA 72 C7 69 87 75 C8 A5 AB 82 AB  w¹‘¿°ÚrÇi‡uÈ¥«‚«
Den första datautskriften är en buffer som jag fyllt med asciitecken. Efter den ser man debuginformationen från när jag försöker skriva till kortet.

MMC Write Block R1=0x0000
Data Response Token=0x0005

Detta betyder att skrivningen lyckades. I mmcWrite skickar jag CMD24 (WRITE_BLOCK) och får 0x00 tillbaka. Sen skickar jag en dummy 0xFF, varför vet jag ej men utan den får jag felmeddelande. Sen skickas 0xFE (STARTBLOCK_WRITE) och efter det skickas bufferten byte bör byte. Slutligen skickas en dummy-CRC. Tillbaks får jag 0xE5 som tillsammans med MMC_DR_MASK (0x1F) blir 0x05 vilket betyder "Data responce accept (DR_ACCEPT). Allt verkar alltså fungera men när jag sedan läser samma block ser man att inget har skrivits, enligt den andra datautskriften.

Jag vet inte om det är nåt uppenbart jag missar. Ska nog ta ett avbrott från just SD-kortbiten av mitt projekt någon dag så att jag kan titta på det med nya ögon sen.

Edit: Tror jag löste det. Satte två pullupmotstånd på de två oanvända pinnarna på kortet (8,9). Ska testa lite mer och återkommer.

Edit2: Ja, nu funkar det att läsa och skriva med Kingston 1GB och CubeMemory 512. Ett tips till alla som försöker använda SD-kort är alltså att ha pullupmotstånd på de oanvända pinnarna samt att skicka minst 8 extra klockcykler efter avslutat kommando. Tack för hjälpen alla!
Skriv svar