?? sd.c
字號:
//*****************************************************************************
//
// File Name : 'sd.c'
// Title : SD Flash Card Interface
// Author : Andy Zhu - Copyright (C) 2008.7
// Created : 2008.07.20
// Revised : 2008.07.20
// Version : 0.1
// Target MCU : Atmel AVR mega128
//
//*****************************************************************************
#include <avr/io.h>
#include <stdint.h>
#include "sd.h"
#include "spi.h"
//CID_Reg *pCID;
//pCID = &SD_CID_infor;
//-----------------------------------
void SD_Init(void)
{
SPI_init();
SD_CS_PORT |= (1<<SD_CS_PIN); //cs=1
SD_CS_DDR |= (1<<SD_CS_PIN); //cs pin output
}
//------------------------------------
uint8_t SD_Reset(void)
{
uint8_t retry = 0;
uint8_t temp ,i;
for (i=0; i<12; i++)
{
spiTransferByte(0xFF);
}
do
{
temp = SD_SendCommand(SD_GO_IDLE_STATE, 0);
retry++;
if(retry>200)
{
return ERROR;
}
}while(temp != SD_R1_IDLE_STATE);
retry = 0;
do
{
// initializing card for operation
temp = SD_SendCommand(SD_SEND_OP_COND, 0);
retry++; // do retry counter
if(retry>100) return ERROR;
}while(temp);
return 0; //初始化成功,返回0
}
//------------------------------------
uint8_t SD_SendCommand(uint8_t cmd, uint32_t arg)
{
uint8_t temp;
spiTransferByte(0xff);
// assert chip select
SD_CS_SELECT();
// issue the command
temp = SD_Command(cmd, arg);
// release chip select
SD_CS_RELEASE();
spiTransferByte(0xff); // extra 8 CLK
return temp;
}
//--------------------------------------------
uint8_t SD_Command(uint8_t cmd, uint32_t arg)
{
uint8_t temp;
uint8_t retry=0;
// send command,every command is 6 bytes long
//|<---BYTE1---->|<------BYTE2~5------>|<----BYTE6------>|
//|7 6|5 0|31 0|7 1|0|
//|0 1|-COMMAND--|---Command Argument--|----- CRC------|1|
spiTransferByte(cmd | 0x40); //send command
spiTransferByte(arg>>24);
spiTransferByte(arg>>16);
spiTransferByte(arg>>8);
spiTransferByte(arg);
spiTransferByte(0x95); //crc valid only for SD_GO_IDLE_STATE
// end command
// wait for response
// if more than 8 retries, card has timed-out
// return the received 0xFF
while((temp = spiTransferByte(0xff)) == 0xff)
if(retry++ > 8) break;
// return response
return temp;
}
//-------------------------------------------
uint8_t Read_SD_Reg(uint8_t *buffer,uint8_t CMD,uint8_t length)
{
uint8_t temp,i;
uint8_t retry;
retry = 0;
spiTransferByte(0xff);
// assert chip select
SD_CS_SELECT();
do
{
temp = SD_Command(CMD, 0); //read CID Register
//temp = SD_Command(SD_SEND_CSD, 0);
retry++;
if (retry >200)
{
SD_CS_RELEASE();
return ERROR;
}
}while(temp != 0x00);
//--------------------------------
if (CMD == SD_APP_CMD)
{
return 0;
}
//-------------------------------
if (CMD != SD_READ_OCR)
while((temp = spiTransferByte(0xff)) != 0xfe); //wait for start byte
for (i=0; i<length ;i++)
{
*buffer++ = spiTransferByte(0xff);
}
temp = spiTransferByte(0xff); //crc1
temp = spiTransferByte(0xff); //crc0
// release chip select
SD_CS_RELEASE();
spiTransferByte(0xff); // extra 8 CLK
return 0;
}
uint8_t SD_ReadSingleBlock(uint32_t sector, uint8_t *buffer)
{
uint16_t retry,i;
uint8_t temp;
retry = 0;
spiTransferByte(0xff);
// assert chip select
SD_CS_SELECT();
do
{
temp = SD_Command(SD_READ_SINGLE_BLOCK, (sector << 9)); //read singblock
retry++;
if (retry >200)
{
SD_CS_RELEASE();
return ERROR;
}
}while(temp != 0x00); //讀到正確的回應
retry = 0;
while((temp = spiTransferByte(0xff)) != 0xfe) //wait for start byte
{
if (retry++ >= 200)
{
SD_CS_RELEASE();
return ERROR;
}
}
for (i=0; i<512 ;i++)
{
*buffer++ = spiTransferByte(0xff);
}
temp = spiTransferByte(0xff); //crc1
temp = spiTransferByte(0xff); //crc0
// release chip select
SD_CS_RELEASE();
spiTransferByte(0xff); // extra 8 CLK
return 0;
}
//-----------------------------------------
void Get_SD_card_CID_Infor(unsigned char *tag_buf)
{
SD_CID_infor.MID = tag_buf[0];
SD_CID_infor.OID |= tag_buf[1];
SD_CID_infor.OID <<= 8;
SD_CID_infor.OID |= tag_buf[2];
SD_CID_infor.PNM[0] = tag_buf[3];
SD_CID_infor.PNM[1] = tag_buf[4];
SD_CID_infor.PNM[2] = tag_buf[5];
SD_CID_infor.PNM[3] = tag_buf[6];
SD_CID_infor.PNM[4] = tag_buf[7];
SD_CID_infor.PRV = tag_buf[8];
SD_CID_infor.PSN[0] = tag_buf[9];
SD_CID_infor.PSN[1] = tag_buf[10];
SD_CID_infor.PSN[2] = tag_buf[11];
SD_CID_infor.PSN[3] = tag_buf[12];
SD_CID_infor.MDT |= tag_buf[13];
SD_CID_infor.MDT <<= 8;
SD_CID_infor.MDT |= tag_buf[14];
SD_CID_infor.CID_CRC7 = tag_buf[15] & 0XFE;
}
//------------------------------------------
void Get_SD_card_CSD_Infor(unsigned char *tag_buf)
{
SD_CSD_infor.CSD_STRUCTURE = tag_buf[0] >> 6;
SD_CSD_infor.TAAC = tag_buf[1];
SD_CSD_infor.NSAC = tag_buf[2];
SD_CSD_infor.TRAN_SPEED = tag_buf[3];
SD_CSD_infor.CCC |= tag_buf[4];
SD_CSD_infor.CCC <<= 4;
SD_CSD_infor.CCC |= (tag_buf[5] & 0XF0) >> 4;
SD_CSD_infor.READ_BL_LEN = tag_buf[5] & 0X0F;
SD_CSD_infor.READ_BL_PARTIAL = (tag_buf[6] & 0X80) >> 7;
SD_CSD_infor.WRITE_BLK_MISALIGN = (tag_buf[6] & 0X40) >> 6;
SD_CSD_infor.READ_BLK_MISALIGN = (tag_buf[6] & 0X20) >> 5;
SD_CSD_infor.DSR_IMP = (tag_buf[6] & 0X10) >> 4;
SD_CSD_infor.C_SIZE |= tag_buf[6];
SD_CSD_infor.C_SIZE <<= 8;
SD_CSD_infor.C_SIZE |= tag_buf[7];
SD_CSD_infor.C_SIZE <<= 2;
SD_CSD_infor.C_SIZE |= (tag_buf[8] >> 6) & 0x03;
SD_CSD_infor.C_SIZE &= 0x0fff;
SD_CSD_infor.VDD_R_CURR_MIN = (tag_buf[8] & 0x3f) >> 3;
SD_CSD_infor.VDD_R_CURR_MAX = tag_buf[8] & 0x07;
SD_CSD_infor.VDD_W_CURR_MIN = (tag_buf[9] & 0xe0) >> 5;
SD_CSD_infor.VDD_W_CURR_MAX = (tag_buf[9] & 0x1f) >> 2;
SD_CSD_infor.C_SIZE_MULT = (tag_buf[9] & 0x03) << 1;
SD_CSD_infor.C_SIZE_MULT |= (tag_buf[10] & 0x80) >> 7;
SD_CSD_infor.ERASE_BLK_EN = (tag_buf[10] & 0x40) >> 6;
SD_CSD_infor.SECTOR_SIZE = (tag_buf[10] & 0x3f) << 1;
SD_CSD_infor.SECTOR_SIZE |= (tag_buf[11] & 0x80) >> 7;
SD_CSD_infor.WP_GRP_SIZE = tag_buf[11] & 0x7f;
SD_CSD_infor.WP_GRP_ENABLE = (tag_buf[12] & 0x80) >> 7;
SD_CSD_infor.R2W_FACTOR = (tag_buf[12] & 0x1f) >> 2;
SD_CSD_infor.WRITE_BL_LEN = (tag_buf[12] & 0x03) << 2;
SD_CSD_infor.WRITE_BL_LEN |= (tag_buf[13] & 0xc0) >> 6;
SD_CSD_infor.WRITE_BL_PARTIAL = (tag_buf[13] & 0x20) >> 5;
SD_CSD_infor.FILE_FORMAT_GRP = (tag_buf[14] & 0x80) >> 7;
SD_CSD_infor.COPY = (tag_buf[14] & 0x40) >> 6;
SD_CSD_infor.PERM_WRITE_PROTECT = (tag_buf[14] & 0x20) >> 5;
SD_CSD_infor.TMP_WRITE_PROTECT = (tag_buf[14] & 0x10) >> 4;
SD_CSD_infor.FILE_FORMAT = (tag_buf[14] & 0x0c) >> 2;
SD_CSD_infor.CSD_CRC7 = tag_buf[15] & 0XFE;
}
//------------------------------------------
void Get_SD_card_OCR_Infor(unsigned char *tag_buf)
{
SD_OCR_infor.OCR_3 = tag_buf[0];
SD_OCR_infor.OCR_2 = tag_buf[1];
SD_OCR_infor.OCR_1 = tag_buf[2];
SD_OCR_infor.OCR_0 = tag_buf[3];
}
//-------------------------------------------
void Get_SD_card_SCR_Infor(unsigned char *tag_buf)
{
SD_SCR_infor.SCR_STRUCTURE = (tag_buf[0] & 0Xf0) >> 4;
SD_SCR_infor.SD_SPEC = tag_buf[0] & 0x0f;
SD_SCR_infor.DATA_STAT_AFTER_ERASE = (tag_buf[1] & 0X80) >> 7;
SD_SCR_infor.SD_SECURITY = (tag_buf[1] & 0X70) >> 4;
SD_SCR_infor.SD_BUS_WIDTHS = tag_buf[1] & 0X0f;
}
//-------------------------------------------
void Get_SD_card_Volume_Infor(void)
{
SD_CAPACITY_infor.Capacity = (((unsigned long int)SD_CSD_infor.C_SIZE+1) \
<< (SD_CSD_infor.READ_BL_LEN + 2)) << SD_CSD_infor.C_SIZE_MULT;
SD_CAPACITY_infor.size_MB = (unsigned int)(SD_CAPACITY_infor.Capacity >> 20);
}
//---------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -