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]&0b00111111);
| 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\t1\t2\t3\t4\t5\t6\t7\t8\t9\tA\tB\tC\td\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
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.
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.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|