📄 mmcprotoal.c
字号:
/*
* Header for MultiMediaCard (MMC)
*
* Copyright (c) 2004 ASIC of SOUTHEAST UNIVERSITY
*
* Many thanks to PESIA!
*
* Based strongly on code by:
*
* Author: Yong-iL Joh <tolkien@mizi.com>
*
* Date : $Date: 2004/12/22 10:02:10 $
*
* Versation : 1.0 $
*
*/
#include "mmcprotocal.h"
#include "mmccore.h"
static int rca =0x10000;
int mmcvoltage = 0;
int mmcioretval;
extern g_busy;
#define PARSE_U32(_buf,_index) (((U32)_buf[_index]) << 24) |\
(((U32)_buf[_index+1]) << 16) |\
(((U32)_buf[_index+2]) << 8) | ((U32)_buf[_index+3])
#define PARSE_U16(_buf,_index) (((U16)_buf[_index]) << 8) | ((U16)_buf[_index+1])
/*
int send_cmd_wait_idle(U32 cmd,U32 arg,U32 com_dat_cont,U32 int_mask )
{
int i;
*(RP)MMCC_STR_STP_CLK=0X5; //stop the card clock
*(RP)MMCC_CLK_RATE=0X7;
*(RP)MMCC_STR_STP_CLK=0XE; //begin the clock
*(RP)MMCC_ARG=arg;
*(RP)MMCC_CMD_DAT_CONT= com_dat_cont;
*(RP)MMCC_CMD=cmd;
*(RP)MMCC_INT_MASK=int_mask;
for(i=0;i<1000;i++)
;
return 0;
}
*/
int send_cmd_wait_idle(U32 cmd,U32 arg,U32 com_dat_cont,U32 int_mask )
{
/*********************************************************************
*参数说明:
* cmd: 命令编号;
* arg: 命令参数;
* com_dat_cont: MMC控制器的CMD_DAT_CONT(命令/控制)寄存器配置;
* int_mask: 中断允许标志;
*********************************************************************/
int i;
U32 result;
*(RP)MMCC_STR_STP_CLK=0X5; //停止MMC时钟
*(RP)MMCC_CLK_RATE=0X7; //重新设置时钟频率
// CLK_20M = APB时钟;CLK_DIV = CLK_20M/64
*(RP)MMCC_STR_STP_CLK=0XE; //以新的频率重启MMC时钟
*(RP)MMCC_ARG=arg;
*(RP)MMCC_CMD_DAT_CONT= com_dat_cont;
*(RP)MMCC_CMD=cmd;
*(RP)MMCC_INT_MASK=int_mask;
for (i=0;i<wait_idle_DELAY;i++)
{ result=*(RP)MMCC_STATUS;
if ((result&0x00000800)==0x00000800)
{ return 0;}
}
return 1;
}
int send_cmd_wait_ocr(U32 cmd,U32 arg,U32 com_dat_cont,U32 int_mask)
{
U32 i;
*(RP)MMCC_ARG = arg;
*(RP)MMCC_CMD_DAT_CONT = com_dat_cont;
//*(RP)MMCC_RES_TO = 0XFF; // if not config ,use default value
//*(RP)MMCC_READ_TO =0XFFFF;
*(RP)MMCC_CMD = cmd;
*(RP)MMCC_INT_MASK = int_mask;
for(i =0; i < 10000; i++)
;
return E_OK;
}
/*
int send_cmd_wait_resp(U32 cmd,U32 arg,U32 com_dat_cont,U32 blk_len,U32 nob,U32 int_mask)
{
U32 i;
U32 status;
*(RP)MMCC_ARG=arg;
*(RP)MMCC_BLK_LEN = blk_len;
*(RP)MMCC_NOB = nob;
*(RP)MMCC_CMD_DAT_CONT= com_dat_cont;
//*(RP)MMCC_RES_TO =0XFF; // if not config ,use default value
//*(RP)MMCC_READ_TO=0XFFFF;
*(RP)MMCC_CMD=cmd;
*(RP)MMCC_DAT_COUNT = (nob*blk_len);
*(RP)MMCC_INT_MASK=int_mask;
for(i =0; i < 100000; i++);
do{
status = *(RP)MMCC_STATUS;
if(status & 0x00000800)
break;
}
while(1);
return E_OK;
}
*/
int send_cmd_wait_resp(U32 cmd,U32 arg,U32 com_dat_cont,U32 blk_len,U32 nob,U32 int_mask)
{
/*********************************************************************
*参数说明:
* cmd: 命令编号;
* arg: 命令参数;
* com_dat_cont: MMC控制器的CMD_DAT_CONT(命令/控制)寄存器配置;
* blk_len: 数据块长度;
* int_mask: 中断允许标志;
*********************************************************************/
U32 i;
*(RP)MMCC_ARG=arg;
*(RP)MMCC_BLK_LEN = blk_len;
*(RP)MMCC_NOB = nob;
*(RP)MMCC_CMD_DAT_CONT= com_dat_cont;
*(RP)MMCC_CMD=cmd;
*(RP)MMCC_DAT_COUNT = (nob*blk_len);
*(RP)MMCC_INT_MASK=int_mask;
for(i =0; i < wait_resp_DELAY; i++);
return E_OK;
}
int send_cmd_wait_stat(U32 cmd,U32 arg,U32 com_dat_cont,U32 blk_len,U32 nob,U32 int_mask)
{
U32 i;
U32 status;
U32 COUNT =0;
*(RP)MMCC_ARG=arg;
*(RP)MMCC_BLK_LEN = blk_len;
*(RP)MMCC_NOB = nob;
*(RP)MMCC_CMD_DAT_CONT= com_dat_cont;
//*(RP)MMCC_RES_TO =0XFF; // if not config ,use default value
//*(RP)MMCC_READ_TO=0XFFFF;
*(RP)MMCC_CMD=cmd;
*(RP)MMCC_DAT_COUNT = (nob*blk_len);
*(RP)MMCC_INT_MASK=int_mask;
do{
for(i =0; i < 10; i++);
COUNT++;
status = *(RP)MMCC_STATUS;
if(status & 0x00000800)
break;
}
while(1);
//printf("COUNT=:%d\n",COUNT);
return E_OK;
}
/*
int check_ocr_reg( )
{
U32 retval;
char i=0;
do{
retval = send_cmd_wait_ocr(MMC_SEND_OP_COND,0X80ff8000,0X85,0XF);
i++;
if (i==2000)
{
mmcvoltage= 0;
return ;
}
}while( ( retval !=E_OK )||( *(RP)MMCC_RESPONSE3<0X80008000) );
mmcvoltage= 1;
return 0;
}
*/
int check_ocr_reg( )
{
U32 retval,rep;
int i=0;
do{
retval = send_cmd_wait_ocr(MMC_SEND_OP_COND,0X80ff8000,0X85,0XF);
i++;
if (i==check_ocr_DELAY) //如果出现MMC卡初始化错误,可适当加大循环次数
{
mmcvoltage= 0;
return 1;
}
rep=*(RP)MMCC_RESPONSE3;
}while( ( retval !=E_OK )||( *(RP)MMCC_RESPONSE3<0X80008000) );
mmcvoltage= 1;
return 0;
}
int card_registry()
{
send_cmd_wait_resp(MMC_ALL_SEND_CID,0X0,0X87,0x0,0x0,0XF);
send_cmd_wait_resp(MMC_SET_RELATIVE_ADDR,rca,0X85,0x0,0x0,0XF);
send_cmd_wait_resp(MMC_SELECT_CARD,0X10000,0X85,0x0,0x0,0XF);
return 0;
}
int mmc_cim_init_stack( void)
{
int retval;
send_cmd_wait_idle(MMC_GO_IDLE_STATE,0x0,0x81,0xF);
check_ocr_reg( );
if(mmcvoltage == 0)
return 0;
card_registry( );
g_busy = 0;
return 1;
}
void gpt_count(void)
{
U32 control;
#define write_reg(reg, data) \
*(RP)reg = data
#define read_reg(reg) \
*(RP)reg
#define s1 0xffffff00//0x186a0
write_reg(GPT1_COMP,s1);
init_gpt1();
}
int init_gpt1(void)
{
U32 control;
//control = GPT_EN|GPT_NOM|GPT_IEN;
control = GPT_EN|GPT_FRU;
write_reg(GPT1_CNTL,control);
return E_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -