Eclipse开发调试ARM裸机程序(七)sd卡读写
时间:11-19
来源:互联网
点击:
运行结果如下:
S3C2440上的寄存器就多了,有几个难以理解的写下来:SDICCON的后7位是发送命令值。但是真正填写的时候并不是命令值而是&上了一个值(0x64),这个还没有找出原因所在。例如如果发送命令2,SDICCON的后7位应该是这样的:(0x40 | 2)。
四、文件系统
如果只是简单的放一个数据,没有文件系统会显示无力,就无法在PC直接上查看。SD卡应该有一个文件系统如常用的fat32。这个u-boot中有实现,这里就先不做了。
五、代码
完整代码这里下载:http://download.csdn.net/detail/kangear/5303482
这里贴出sdi.c:
/* @file sdi.c* @brief sd卡 读写* @details 本程序实现了,读SD卡的CSD寄存器;读写SD卡,并用LED显示。* 程序正常:led1首先点亮,然后是0-15的二进制显示* 程序出错:led2首先点亮,然后是乱无序的二进制显示* 目前只能读写2G以下的SD卡* (启动代码是适用于mini2440 nand 256M的开发板)* 读写SD有三种模式:中断,DMA中断,查询。本程序使用的是查询* @author kangear* @date 2013-4-26* @version A001* @par Copyright (c):* XXX公司* @par History:* version: author, date, desc\n** docs 1.SD Specifications Part 1 Physical Layer Simplified Specification Version 4.10 January 22, 2013.pdf* 2.SD Specifications Part A1 Advanced Security SD Extension Simplified Specification Version 2.00 May 18, 2010.pdf* 3.SD Specifications Part A2 SD Host Controller Simplified Specification Version 3.00 February 25, 2011.pdf* 4.SD Specifications Part E1 SDIO Simplified Specification Version 3.00 February 25, 2011.pdf** download addr:https://www.sdcard.org/downloads/pls/simplified_specs/*///#include//#include #include "def.h"//#include "option.h"//#include "2440addr.h"#include "s3c24xx.h"//#include "2440lib.h"#include "sdi.h"/** 用在SDICCON中的[7:0] 现在没有搞懂它的实际意义* CMD1 = MAGIC_NUMBER | 1*/#define MAGIC_NUMBER 64#define INICLK 300000#define SDCLK 24000000 //PCLK=49.392MHz#define POL 0#define INT 1#define DMA 2int CMD13(void); // Send card statusint CMD9(void);unsigned int *Tx_buffer; //128[word]*16[blk]=8192[byte]unsigned int *Rx_buffer; //128[word]*16[blk]=8192[byte]volatile unsigned int rd_cnt;volatile unsigned int wt_cnt;volatile unsigned int block;volatile unsigned int TR_end=0;int Wide=0; // 0:1bit, 1:4bitint MMC=0; // 0:SD , 1:MMCint Maker_ID;char Product_Name[7]; int Serial_Num;int PCLK = 50000000;volatile int RCA;void Test_SDI(void){U32 save_rGPEUP, save_rGPECON;RCA=0;MMC=0;block=3072; //3072Blocks=1.5MByte, ((2Block=1024Byte)*1024Block=1MByte)save_rGPEUP=GPEUP;save_rGPECON=GPECON;GPEUP = 0xf83f; // SDCMD, SDDAT[3:0] => PU En.GPECON = 0xaaaaaaaa; //SDCMD, SDDAT[3:0]//Uart_Printf("\nSDI Card Write and Read Test\n");if(!SD_card_init())return;TR_Buf_new();Wt_Block();Rd_Block();View_Rx_buf();Card_sel_desel(0); // Card deselectif(!CMD9())//Uart_Printf("Get CSD fail!!!\n");SDIDCON=0;//tark???SDICSTA=0xffff;GPEUP=save_rGPEUP;GPECON=save_rGPECON;}void TR_Buf_new(void){//-- Tx & Rx Buffer initializeint i, j;Tx_buffer=(unsigned int *)0x31000000;j=0;for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]*(Tx_buffer+i)=i+j;Flush_Rx_buf();}void Flush_Rx_buf(void){//-- Flushing Rx buffer int i;Rx_buffer=(unsigned int *)0x31800000;for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]*(Rx_buffer+i)=0;//Uart_Printf("End Rx buffer flush\n");}void View_Rx_buf(){//-- Display Rx buffer int i,error=0;Tx_buffer=(unsigned int *)0x31000000;Rx_buffer=(unsigned int *)0x31800000;//Uart_Printf("Check Rx data\n");for(i=0;i<128*block;i++){if(Rx_buffer[i] != Tx_buffer[i]){//Uart_Printf("\nTx/Rx error\n");//Uart_Printf("%d:Tx-0x%08x, Rx-0x%08x\n",i,Tx_buffer[i], Rx_buffer[i]);error=1;break;}////Uart_Printf(".");}if(!error){//Uart_Printf("\nThe Tx_buffer is same to Rx_buffer!\n");//Uart_Printf("SD CARD Write and Read test is OK!\n");}}void View_Tx_buf(void){}int SD_card_init(void){//-- SD controller & card initialize int i;/* Important notice for MMC test condition *//* Cmd & Data lines must be enabled by pull up resister */SDIPRE=PCLK/(INICLK)-1; // 400KHz//Uart_Printf("Init. Frequency is %dHz\n",(PCLK/(SDIPRE+1)));SDICON=(1<4)|1; // Type B, clk enableSDIFSTA=SDIFSTA|(1<16); //YH 040223 FIFO resetSDIBSIZE=0x200; // 512byte(128word)SDIDTIMER=0x7fffff; // Set timeout countfor(i=0;i<0x1000;i++); // Wait 74SDCLK for MMC cardCMD0();//Uart_Printf("In idle\n");//-- Check SD card OCRif(!Chk_SD_OCR()){// failGPBDAT = (~(2<5)); // 点亮LED2//Uart_Printf("Initialize fail\nNo Card assertion\n");return 0;}// Uart_Printf("In SD ready\n");GPBDAT = (~(1<5)); // 点亮LED1do{//-- Check attaced cards, it makes card identification stateSDICARG = 0x0; // CMD2(stuff bit)SDICCON = (0x1 < 10) | (0x1 < 9) | (0x1 < 8) | (MAGIC_NUMBER | 2); //lng_resp, wait_resp, start, CMD2//-- Check end of CMD2} while (!Chk_CMDend(2, 1));SDICSTA=0xa00; // Clear cmd_end(with rsp)//Uart_Printf("End id\n");do{//--Send RCASDICARG = MMC < 16; // CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ)SDICCON = (0x1 < 9) | (0x1 < 8) | (MAGIC_NUMBER | 3); // sht_resp, wait_resp, start, CMD3//-- Check end of CMD3if (!Chk_CMDend(3, 1))continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)//--Publish RCARCA = (SDIRSP0 & 0xffff0000) >> 16;//Uart_Printf("RCA=0x%x\n",RCA);SDIPRE = PCLK / (SDCLK) - 1; // Normal clock=25MHz//Uart_Printf("SD Frequency is %dHz\n",(PCLK/(SDIPRE+1)));//--State(stand-by) checkif (SDIRSP0 & 0x1e00 != 0x600) // CURRENT_STATE checkcontinue;} while (0);//Uart_Printf("In stand-by\n");Card_sel_desel(1); // SelectSet_4bit_bus();return 1;}void Card_sel_desel(char sel_desel){//-- Card select or deselectif(sel_desel){do{SDICARG = RCA < 16; // CMD7(RCA,stuff bit)SDICCON = (0x1 < 9) | (0x1 < 8) | (MAGIC_NUMBER | 7); // sht_resp, wait_resp, start, CMD7//-- Check end of CMD7if (!Chk_CMDend(7, 1))continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)//--State(transfer) checkif (SDIRSP0 & 0x1e00 != 0x800)continue;} while (0);}else{do{SDICARG = 0 < 16; //CMD7(RCA,stuff bit)SDICCON = (0x1 < 8) | (MAGIC_NUMBER | 7); //no_resp, start, CMD7//-- Check end of CMD7if (!Chk_CMDend(7, 0))continue;} while (0);SDICSTA=0x800; // Clear cmd_end(no rsp)}}//void __irq Rd_Int(void)//{// U32 i,status;//// status=SDIFSTA;// if( (status&0x200) == 0x200 ) // Check Last
Eclipse开发调试ARM裸机程序sd卡读 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)