Mikrocontroller und Digitale Elektronik
›
Thread
SD SPI Bytes lesen
FW
Flo W.
(florian1x)
OP
(Firma: privat)
30.05.2011 14:26
#2204616
Hallo,
ich habe ein Problem Bytes zu lesen
hier mal mein Code
1 #ifndef __SDCARD__
2 #define __SDCARD__
3
4 /* Includes */
5 #include "../uart/uart.h"
6 #include "../spi/spi.h"
7 #include <util/delay.h>
8
9 #ifndef DEBUG
10 #define DEBUG //Should be only defined if Debug messages are needed
11 #endif
12
13 /*spi methods*/
14 #define spi_send_byte(x) spi2_transmit(x) //Method to transmit a Byte via SPI
15 #define spi_speed_low() {SPSR|=(1<<SPI2X);SPCR|=(1<<SPR1);SPCR&=~(1<<SPR0);} //sets SPI Clockrate between 100kHz and 400kHz
16
17
18 #define spi_speed_high() {SPSR&=~(1<<SPI2X);SPCR&=~(1<<SPR1);SPCR&=~(1<<SPR0);} //sets SPI Clockrate to maximum
19
20 /*defines for Hardware Initialisation*/
21 #define SD_CS_PIN PC6 //Chipselect for SD Card
22 #define SD_CS_PORT PORTC //Port of SD_CS
23 #define SD_CS_DDR DDRC //Data Direction Register for SD_CS
24
25 #define sd_cs_low() SD_CS_PORT &= ~(1 << SD_CS_PIN) // SD_CS -> '1'
26 #define sd_cs_high() SD_CS_PORT |= (1 << SD_CS_PIN) // SD_CS -> '0'
27
28 /*some other defines:*/
29 #define SD_INIT_TIMEOUT 30 //value between 0 and 254
30 #define SD_HCS 1 // 0 = SDHC disable, 1 = SDHC enable
31
32 /*SD Card Versions*/
33 #define SD_UNSUPPORTED 0
34 #define SD_SPEC1 1
35 #define SD_SPEC2 2
36 #define SD_SDHC 3
37
38 /*
39 Command defines:
40
41 Command Format (6 Bytes):
42 start bit ('0') + transmission bit('1') + command index (6bit) + arguments (4 byte) + CRC7 (7bit)+ end bit('1')
43 */
44
45 /*SPI specifik commands (start bit+transmission bit+command index):*/
46 #define SD_GO_IDLE_STATE 0x00 //CMD0
47 #define SD_SEND_OP_COND 0x01 //CMD1
48 #define SD_SWITCH_FUNC 0x06 //CMD6
49 #define SD_SEND_IF_COND 0x08 //CMD8
50 #define SD_SEND_CSD 0x09 //CMD9
51 #define SD_SEND CID 0x0A //CMD10
52 #define SD_STOP_TRANSMISSION 0x0C //CMD12
53 #define SD_SEND_STATUS 0x0D //CMD13
54 #define SD_SET_BLOCKLEN 0x10 //CMD16
55 #define SD_READ_SINGLE_BLOCK 0x11 //CMD17
56 #define SD_READ_MULTIPLE_BLOCK 0x12 //CMD18
57 #define SD_WRITE_BLOCK 0x18 //CMD24
58 #define SD_WRITE_MULTIPLE_BLOCK 0x19 //CMD25
59 #define SD_PROGRAM_CSD 0x1B //CMD27
60 #define SD_SET_WRITE_PROT 0x1C //CMD28
61 #define SD_CLR_WRITE_PROT 0x1D //CMD29
62 #define SD_SEND_WRITE_PROT 0x1E //CMD30
63 #define SD_ERASE_WR_BLK_START_ADDR 0x20 //CMD32
64 #define SD_ERASE_WR_BLK_END_ADDR 0x21 //CMD33
65 #define SD_ERASE 0x26 //CMD38
66 #define SD_LOCK_UNLOCK 0x2A //CMD42
67 #define SD_APP_CMD 0x37 //CMD55
68 #define SD_GEN_CMD 0x38 //CMD56
69 #define SD_READ_OCR 0x3A //CMD58
70 #define SD_CRC_ON_OFF 0x3B //CMD59
71
72 #define SD_SD_SEND_OP_COND 0x29 //ACMD41s
73
74 #define SD_CMD_MASK 0x40; //star bit and transmission bit
75
76 /* command responses */
77 /* Format R1 (1 byte)*/
78 #define SD_R1_IDLE_STATE 1
79 #define SD_R1_ERASE_RESET 2
80 #define SD_R1_ILLEGAL_COMMAND 3
81 #define SD_R1_COM_CRC_ERR 4
82 #define SD_R1_ERASE_SEQ_ERR 5
83 #define SD_R1_ADDRESS_ERR 6
84 #define SD_R1_PARAMETER_ERR 7
85
86 /* Format R3 (5 bytes)*/
87 #define SD_R3_IDLE_STATE 33
88 #define SD_R3_ERASE_RESET 34
89 #define SD_R3_ILLEGAL_COMMAND 35
90 #define SD_R3_COM_CRC_ERR 36
91 #define SD_R3_ERASE_SEQ_ERR 37
92 #define SD_R3_ADDRESS_ERR 38
93 #define SD_R3_PARAM_ERR 39
94
95 /*Methods*/
96
97 //initialize SD Card
98 uint8_t sd_init ( void );
99
100 //Sends a 6 Byte long SD/MMC-Cardcommand via SPI
101 uint8_t sd_send_cmd ( uint8_t , uint32_t , uint8_t );
102
103 //Reads the next 4 Bytes after a command with R3 response
104 uint32_t sd_read_four_byte ( void );
105
106 uint8_t sd_read_single_block ( uint32_t , uint8_t * buffer , uint16_t );
107
108 void sd_print_buffer ( uint8_t * buffer , uint16_t );
109 #endif
------------------------------------------------------------
die c file zur h
1 #include "sd.h"
2
3 volatile uint8_t sdversion = SD_UNSUPPORTED ;
4
5 // Method to initialize SDCard/MMC after Powerup
6 // name: sd_init()
7 // @param
8 // @return returns type of inserted Card
9
10 uint8_t sd_init (){
11
12 spi_speed_low ();
13
14 /* Hardware initialisation */
15
16 //Chips select for SDCard to output
17 SD_CS_DDR |= ( 1 << SD_CS_PIN );
18 //CS to logic 1
19 sd_cs_high ();
20 //wait 1 ms
21 _delay_ms ( 1 );
22 //send 74+ dummy clocks
23 for ( uint8_t i = 0 ; i < 8 ; i ++ )
24 spi_send_byte ( 0xFF );
25
26 /* Software initialisation - Go IDLE MODE */
27
28 #ifdef DEBUG
29 printf ( "Go IDLE mode ... \n " );
30 #endif
31
32 uint8_t timeout = SD_INIT_TIMEOUT ;
33 uint8_t rec = 0 ;
34
35 //CMD0 to get Card into IDLE State
36 while ( rec != 1 ){
37 rec = sd_send_cmd ( SD_GO_IDLE_STATE , 0 , 0x95 );
38 if ( ! timeout -- ){
39 #ifdef DEBUG
40 printf ( "Timeout reached. Stop card initialisation \n " );
41 #endif
42 return sdversion = SD_UNSUPPORTED ;
43 }
44 }
45
46 /* Software initialisation - Card verification */
47
48 #ifdef DEBUG
49 printf ( "Card is in IDLE mode. Begin to verify version \n " );
50 #endif
51
52 //send CMD08
53 rec = sd_send_cmd ( SD_SEND_IF_COND , 0x1AA , 0x87 );
54
55 if ( rec == 0x05 ){ //means SDC V1 or MMC
56 sdversion = SD_SPEC1 ;
57 #ifdef DEBUG
58 printf ( "MMC/SDCV1 \n " );
59 #endif
60 } else {
61 uint32_t ocr = sd_read_four_byte ();
62
63 if (( ocr & 0x0FFF ) == 0x01AA ){ //means SDC V2
64 #ifdef DEBUG
65 sdversion = SD_SPEC2 ;
66 printf ( "SDCV2 \n " );
67 #endif
68 }
69 rec = sd_send_cmd ( SD_READ_OCR , 0 , 0 );
70 sd_read_four_byte ();
71 }
72
73 /* Software initialisation - Initialisation with ACMD41 */
74
75 timeout = SD_INIT_TIMEOUT ;
76 while ( rec ){
77 sd_send_cmd ( SD_APP_CMD , 1L << 30 , 0xFF ); //CMD55
78 rec = sd_send_cmd ( SD_SD_SEND_OP_COND , 1L << 30 , 0xFF ); //ACMD41
79 if ( ! ( -- timeout )){
80 #ifdef DEBUG
81 printf ( "Timeout reached. Stop card initialisation with ACMD41 \n " );
82 #endif
83 break ;
84 }
85 }
86
87 /* Software initialisation - Initialisation with CMD1 */
88 #ifdef DEBUG
89 if ( rec )
90 printf ( "Try to initiate with CMD1 \n " );
91 #endif
92 timeout = SD_INIT_TIMEOUT ;
93 while ( rec ){
94 rec = sd_send_cmd ( SD_SEND_OP_COND , 0 , 0xFF ); //CMD1
95 if ( ! ( -- timeout )){
96 #ifdef DEBUG
97 printf ( "Timeout reached. Stop card initialisation \n " );
98 #endif
99 return sdversion = SD_UNSUPPORTED ;
100 }
101 }
102
103 spi_speed_high ();
104 return rec ;
105 }
106
107 // Sends a command to SDC via SPI and returns R1
108 // name: sd_hw_init
109 // @param cmd command for SD Card
110 // @param arg Arguments for the CMD
111 // @param crc checksum
112 // @return command response in R1 format
113
114 uint8_t sd_send_cmd ( uint8_t cmd , uint32_t arg , uint8_t crc ){
115
116 /*build complete Command*/
117 uint8_t buffer [ 6 ] ; //temporary Buffer for the CMD
118 buffer [ 0 ] = cmd | SD_CMD_MASK ; //Set start and transmission bit + Command
119 buffer [ 1 ] = ( arg & 0xFF000000 ) >> 24 ; //Set parameter byte 1
120 buffer [ 2 ] = ( arg & 0x00FF0000 ) >> 16 ; //Set parameter byte 2
121 buffer [ 3 ] = ( arg & 0x0000FF00 ) >> 8 ; //Set parameter byte 3
122 buffer [ 4 ] = ( arg & 0x000000FF ); //Set parameter byte 4
123 buffer [ 5 ] = crc | 0x01 ; //CRC + Endbit '1'
124
125 #ifdef DEBUG
126 //Prints the Command
127 printf ( "Sending CMD: " );
128 printf ( "%d, " , buffer [ 0 ] & 0 b00111111 );
129 printf ( "ARGS: " );
130 for ( uint8_t i = 1 ; i < 5 ; i ++ )
131 printf ( "0x%x, " , buffer [ i ]);
132 printf ( "CRC: 0x%x, " , buffer [ 5 ]);
133 #endif
134
135 sd_cs_low ();
136 spi_send_byte ( 0xFF );
137
138 //Send complete Command via SPI
139 for ( uint8_t i = 0 ; i < 6 ; i ++ )
140 spi_send_byte ( buffer [ i ]);
141
142 //receive answer byte
143 uint8_t ret = 0xFF ;
144 uint8_t timeout = 0 ;
145 while ( ret == 0xFF ){
146 ret = spi_send_byte ( 0xFF );
147 if ( timeout ++> 100 )
148 break ;
149 }
150
151 sd_cs_high (); //clear SPI
152 #ifdef DEBUG
153 //Prints the Command
154 printf ( "recv.: 0x%x" , ret );
155 printf ( ". \n " );
156 #endif
157
158 return ret ;
159 }
160
161 uint32_t sd_read_four_byte (){
162 uint32_t values = ( uint32_t ) spi_send_byte ( 0xFF ) << 24 ;
163 values |= ( uint32_t ) spi_send_byte ( 0xFF ) << 16 ;
164 values |= ( uint32_t ) spi_send_byte ( 0xFF ) << 8 ;
165 values |= spi_send_byte ( 0xFF );
166
167 #ifdef DEBUG
168 printf ( "ocr: 0x%x 0x%x 0x%x 0x%x \n " , ( uint8_t )(( values >> 24 ) & 0xFF ), ( uint8_t )(( values >> 16 ) & 0xFF ), ( uint8_t )(( values >> 8 ) & 0xFF ), ( uint8_t )( values & 0xFF ));
169 #endif
170 return values ;
171 }
172
173 uint8_t sd_read_single_block ( uint32_t startBlock , uint8_t * buffer , uint16_t buf_size ){
174
175 //Send command to MMC/SDC/SDHC Card
176 uint8_t rec = sd_send_cmd ( SD_READ_SINGLE_BLOCK , startBlock , 0xFF ); //read a Block command
177
178 //Check for errors
179 if ( rec != 0x00 )
180 return rec ;
181
182 /*read Bytes and write to Buffer*/
183 sd_cs_low ();
184
185 //Wait for startbyte
186 uint8_t timeout = 100 ;
187 while ( spi_send_byte ( 0xFF ) != 0xfe ){
188 if ( timeout -- ){
189 sd_cs_high ();
190 return 0 ;
191 }
192 }
193
194 //Read Block
195 while ( buf_size -- ){ //read buf_size bytes
196 * buffer ++ = spi_send_byte ( 0xFF );
197
198 }
199 //receive CRC
200 spi_send_byte ( 0xFF ); //ignored
201 spi_send_byte ( 0xFF ); //ignored
202
203 sd_cs_high ();
204
205 return 1 ;
206 }
207
208 #ifdef DEBUG
209 void sd_print_buffer ( uint8_t * buffer , uint16_t buf_size ){
210 printf ( "read %d Bytes after address %p \n " , buf_size , & buffer );
211 printf ( "offset \t 1 \t 2 \t 3 \t 4 \t 5 \t 6 \t 7 \t 8 \t 9 \t A \t B \t C \t d \n " );
212 uint8_t offset = 0 ;
213 for ( uint8_t i = 0 ; i < buf_size ; i = i + 16 ){
214 printf ( "0x%x" , offset ++ ); //Offset
215 printf ( " \t %x" , * buffer ++ ); //1
216 printf ( " \t %x" , * buffer ++ ); //2
217 printf ( " \t %x" , * buffer ++ ); //3
218 printf ( " \t %x" , * buffer ++ ); //4
219 printf ( " \t %x" , * buffer ++ ); //5
220 printf ( " \t %x" , * buffer ++ ); //6
221 printf ( " \t %x" , * buffer ++ ); //7
222 printf ( " \t %x" , * buffer ++ ); //8
223 printf ( " \t %x" , * buffer ++ ); //9
224 printf ( " \t %x" , * buffer ++ ); //A
225 printf ( " \t %x" , * buffer ++ ); //B
226 printf ( " \t %x" , * buffer ++ ); //C
227 printf ( " \t %x" , * buffer ++ ); //D
228 printf ( " \t %x" , * buffer ++ ); //E
229 printf ( " \t %x" , * buffer ++ ); //F
230 printf ( " \n " );
231 }
232 }
233 #endif
-------------------------------------------------
und die main:
1 /*
2 Name: main.c
3 Author: Mathäus Sander & Florian Weinhold
4
5 Desc.: Main Programm for testing purposes
6 License: LGPL
7 */
8
9
10 #define F_CPU 20000000L
11 #define BAUD 9600L
12 #define DEBUG
13
14 #include <avr/io.h>
15 #include <util/delay.h>
16 #include "uart/uart.h"
17 #include "spi/spi.h"
18 #include "sd/sd.h"
19 #include "enc28j60/enc28j60.h"
20
21 int main ( void ) {
22
23 USART_Init ();
24 SPI1_Init (); //ENC OR SDCard
25 SPI2_Init (); //ENC OR SDCard
26
27 printf ( "Welcome to WeSa System v0.0.1a \n " );
28
29 printf ( "Starting SD initialsation. \n " );
30
31 printf ( "%x" , sd_init ());
32 uint8_t buff [ 32 ];
33 sd_read_single_block ( 0 , buff , 32 );
34 sd_print_buffer ( buff , 32 );
35 while ( 1 ) {
36 _delay_ms ( 500 );
37 }
38
39 return 0 ;
40 }
ich hoffe das reicht an quelltext.
ich versuche derzeit die ersten 32 byte der karte zu lesen. bekomme aber
nur nullen raus.
Hardware: Myethernet 2.03, Uart über MySmartUsb, Kingston 4GB SDHC karte
Also initialisieren klappt soweit ... nur habe ich hinterher nur nullen
drin stehen. Weiss einer woran das liegt?
mfG Flo
Hallo,
welche spi.h verwendest du?
'spi_send_byte' gibt glaube ich keinen Wert zurück, wie wärs mit
'spi_Transfer_Byte'
Sascha
FW
Flo W.
(florian1x)
OP
(Firma: privat)
31.05.2011 08:38
#2205560
oh das hätte ich vlt noch dazu packen sollen, ich verwende meine eigene
SPI methoden. Funktionieren auch soweit. Ich gebe halt das Byte zurück
welches mit der clock ankommt in der ich auch sende.
meine ausgabe in GTKTerm sieht wie folgt aus:
UART Initialized
SPI Initialized
USART as SPI Initialized
Welcome to WeSa System v0.0.1a
Starting SD initialsation.
Go IDLE mode ...
Sending CMD: 0, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0x95, recv.: 0x1.
Card is in IDLE mode. Begin to verify version
Sending CMD: 8, ARGS: 0x0, 0x0, 0x1, 0xaa, CRC: 0x87, recv.: 0x1.
ocr: 0x0 0x0 0x0 0x0
Sending CMD: 58, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0x1, recv.: 0x1.
ocr: 0x0 0x0 0x0 0x0
Sending CMD: 55, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x1.
Sending CMD: 55, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x0.
0Sending CMD: 17, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x0.
read 32 Bytes after address 0x10cc
offset 1 2 3 4 5 6 7 8 9 A B C D E F
0x0 2c e3 f5 aa ff f 69 c2 a2 cf ad 98 fe 7d f8
0x1 cf 5e 3d f1 60 d4 eb e9 67 99 8 d8 f7 c5 f6
edit ... ok ich hab seid gestern ncihts mehr gemacht und auf einma
spuckt der was aus.
FW
Flo W.
(florian1x)
OP
(Firma: privat)
31.05.2011 09:11
#2205585
Ok nachdem es nun einige male Werte ausgegeben hat, jedoch andere, wie
die die bei mir in WinHex angezeigt werden. Kommt nun wieder nix
UART Initialized
SPI Initialized
USART as SPI Initialized
Welcome to WeSa System v0.0.1a
Starting SD initialsation.
Go IDLE mode ...
Sending CMD: 0, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0x95, recv.: 0x1f.
Sending CMD: 0, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0x95, recv.: 0x5.
Sending CMD: 0, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0x95, recv.: 0x1.
Card is in IDLE mode. Begin to verify version
Sending CMD: 8, ARGS: 0x0, 0x0, 0x1, 0xaa, CRC: 0x87, recv.: 0x1.
ocr: 0x0 0x0 0x0 0x0
Sending CMD: 58, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0x1, recv.: 0x1.
ocr: 0x0 0x0 0x0 0x0
Sending CMD: 55, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x1.
Sending CMD: 55, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x1.
Sending CMD: 41, ARGS: 0x40, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x0.
0Sending CMD: 17, ARGS: 0x0, 0x0, 0x0, 0x0, CRC: 0xff, recv.: 0x0.
read 32 Bytes
offset 1 2 3 4 5 6 7 8 9 A B C D E F
0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
anfangs will cmd0 aber auch nicht so recht vlt liegs auch daran.
FW
Flo W.
(florian1x)
OP
(Firma: privat)
31.05.2011 10:54
#2205726
ahhh fail, hab meinen fehler :), hatte die Abfrage zum timeout falsch,
weshalb der immer direkt aus der Methode raus is. Aber der liest dann
ziehmlich lange.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren