s5pv210-裸机之SD卡

来源:互联网 发布:数据修炼系统下载 编辑:程序博客网 时间:2024/06/05 06:22
    

    sd卡共支持三种传输模式:spi模式、1sd模式、4sd模式。所有的sd卡都必须支持较老的spi/mmc模式,这个模式支持慢速的四线spi接口,使很多微控制器都可以通过spi或模拟spi接口来读写sd卡。由于S5PV210具有sd总线控制器,并且兼容sd2.0sd卡,因此此处只分析4sd模式、sd2.0sd1.0版本的sd卡驱动实现,sd2.0以上版本sd卡、MMC卡、spi方式读写sd卡在本文不适用。

1、S5PV210的HSMMC主机控制器初始化

// 配制IO引脚为SDIO功能GPG0CON = 0x2222222;// 禁止上下拉GPG0PUD = 0;//GPG0PUD = 0x2AAAA; // 配制时钟源:channel 0 clock src = SCLKEPLL = 96MCLK_SRC4 = (CLK_SRC4 & (~(0xf<<0))) | (0x7<<0);// 时钟分频:channel 0 clock = SCLKEPLL/2 = 48MCLK_DIV4 = (CLK_DIV4 & (~(0xf<<0))) | (0x1<<0);// software reset for allSWRST0 = 1;timeout = 1000;temp = SWRST0;while (SWRST0 & (1<<0)){if (timeout == 0){return -1;// reset timeout}timeout--;delay(US * 10);}// 设置sd卡时钟在100k~400k,sd卡在识别阶段必须用慢速时钟进行访问s5pHsmmcSetClock(400000);// 400k
首先,配制控器制的时钟源,然后重启控制器,最后把SD卡时钟设置为400K


2、向SD卡发送命令函数

// 命令发送时,需检查命令线是否已被使用,否则需要等待正在发送的命令发送完才能发送这个命令for (i = 0; i < 0x1000000; i++){if (!(PRNSTS0 & (1 << 0))){break;}}if (i == 0x1000000){Debug("CMD line time out, PRNSTS: %04x\r\n", PRNSTS0);return -1; // 命令超时}// 如果命令回复会带忙信号(如R1b回复),则需检查数据线是否已被使用// 若是,则等待数据线空闲,带忙回复命令发送后,sd卡会拉低DAT[0]线表明sd卡正忙,数据线不可用if (response == CMD_RESP_R1B) // R1b回复通过DAT0反馈忙信号{for (i = 0; i < 0x10000000; i++){if (!(PRNSTS0 & (1 << 1))){break;}}if (i == 0x10000000){Debug("Data line time out, PRNSTS: %04x\r\n", PRNSTS0);return -2;}}ARGUMENT0 = arg;// 把命令参数写入ARGUMENT这个寄存器中value = (cmd << 8);// command index 在CMDREG中设置命令值[13:8]// CMD12可终止传输if (cmd == 0x12){value |= (0x3 << 6); // command type}// 设置是否需使用data线,如块读,块写等命令发送后// 会紧接着在data线上传输数据,其它不需传输数据的命令不要设置使用data线CMDREG[5]if (data){value |= (1 << 5); // 需使用DAT线作为传输等}// 设置sd卡的回复类型,绝大部分命令在sd卡正确响应后,都会对主机进行回复(R1-R7,R1b)// 每个命令对应的回复类型请参考sd卡规范,回复类型长度可能为136或48// 回复中是否包含CRC或命令值的反馈,如果包含,则告诉主控制器检查回复中相应的CRC或命令值反馈是否正确以确定传输正确// CMDREG设置好后,主控制器就会发送命令并接收设定长度的回复并根据设定检查CRC,命令值反馈是否正确(若回复中包含CRC或命令值反馈的话)switch (response){case CMD_RESP_NONE:value |= (0 << 4) | (0 << 3) | 0x0; // 没有回复,不检查命令及CRCbreak;case CMD_RESP_R1:case CMD_RESP_R5:case CMD_RESP_R6:case CMD_RESP_R7:value |= (1 << 4) | (1 << 3) | 0x2; // 检查回复中的命令,CRCbreak;case CMD_RESP_R2:value |= (0 << 4) | (1 << 3) | 0x1; // 回复长度为136位,包含CRCbreak;case CMD_RESP_R3:case CMD_RESP_R4:value |= (0 << 4) | (0 << 3) | 0x2; // 回复长度48位,不包含命令及CRCbreak;case CMD_RESP_R1B:value |= (1 << 4) | (1 << 3) | 0x3; // 回复带忙信号,会占用Data[0]线break;default:break;}CMDREG0 = value;errorState = s5pHsmmcWaitForCommandDone();if (errorState){Debug("Command = %d\r\n", cmd);}return errorState; // 命令发送出错
首先,检查命令线是否被占用,如果被占用了,则需要等待其空闲,然后,判断是否需要使用数据线,最后判断命令的回复型式。


3、SD卡初始化

s5pHsmmcIssueCommand(CMD0, 0, 0, CMD_RESP_NONE);
发送CMD0命令,复位SD卡


s5pHsmmcIssueCommand(CMD8, 0x1aa, 0, CMD_RESP_R7)
发送CMD8来检查卡是否支持主机电压(2.7v~3.3v),没有回复,说明是MMC/sd v1.x/not card


s5pHsmmcIssueCommand(CMD55, 0, 0, CMD_RESP_R1);s5pHsmmcIssueCommand(CMD41, 0, 0, CMD_RESP_R3)
进一步发送ACMD41(CMD55+CMD41),参数HCS位为0(非高容量卡)


如果CMD8命令接收到卡回复信号,说明为sd2.0版本卡

s5pHsmmcIssueCommand(CMD55, 0, 0, CMD_RESP_R1);s5pHsmmcIssueCommand(CMD41, OCR, 0, CMD_RESP_R3); 
进一步发送ACMD41(CMD55+CMD41),判断SD卡是sd2.0高容量sdhc卡或者是sd2.0标准容量卡

s5pHsmmcIssueCommand(CMD3, 0, 0, CMD_RESP_R6);
发送CMD3请求卡发布一个16位新的相对地址(RCA)


s5pHsmmcIssueCommand(CMD16, 512, 0, CMD_RESP_R1)
通过CMD16设置块长度为512字节

4、读SD卡

// 根据sd主机控制器标准,按顺序写入主机控制器相应的寄存器BLKSIZE0 = (7 << 12) | (512 << 0);// 最大DMA缓存大小,block为512字节BLKCNT0  = readBlock;// 写入这次读block数目// 设置命令寄存器,单块读CMD17,R1回复CMDREG0 = (CMD17 << 8) | (1 << 5) | (1 << 4) | (1 << 3) | 0x2;// 设置命令寄存器,多块读CMD18,R1回复CMDREG0 = (CMD18 << 8) | (1 << 5) | (1 << 4) | (1 << 3) | 0x2;for (j = 0; j < 512/4; j++){*(unsigned int *)pBuffer = BDATA0;pBuffer += 4;}

首先,确定要读的块数目,然后设置是读单块还是读多块,最后从数据寄存器读出数据。


5、写SD卡

BLKSIZE0 = (7 << 12) | (512 << 0);// 最大DMA缓存大小,block为512字节BLKCNT0  = writeBlock;// 写入block数目// 设置命令寄存器,单块写CMD24,R1回复CMDREG0 = (CMD24 << 8) | (1 << 5) | (1 << 4) | (1 << 3) | 0x2;// 设置命令寄存器,多块写CMD25,R1回复CMDREG0 = (CMD25 << 8) | (1 << 5) | (1 << 4) | (1 << 3) | 0x2;for (j = 0; j < 512/4; j++){BDATA0 = *(unsigned int *)pBuffer;pBuffer += 4;}
首先,确定写入的块数,然后设置是写单块还是多块,最后把数据写入寄存器。

6、

sd卡驱动的编写必须参考sd2.0规范,此处只根据sd2.0规范讲解几个重要的过程或概念,这些过程具体的实现请参考sd驱动模块中相应的函数实现。


程序完整代码已上传

http://download.csdn.net/download/wzs250969969/10122049






原创粉丝点击