⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mspro.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 3 页
字号:
	kal_uint32 flags;

	MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_CMD);
	kal_retrieve_eg_events(MSDC_Events,EVENT_MSRDYIRQ,KAL_AND_CONSUME,&flags,KAL_SUSPEND);	
	MSDC_STOP_TIMER();
#else	
{
	kal_uint32 t1;

	t1 = drv_get_current_time();
	MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_DAT);
	while(!MSDC_IS_INT && MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
	{
		if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
			gMSDC_Handle.is_timeout = KAL_TRUE;
	}
	MSDC_STOP_TIMER();
	MSDC_CLR_INT();	
}
#endif

	msc_sta = *(volatile kal_uint16*)MSC_STA;
	if(msc_sta & MSC_STA_CRCERR)
		return MSP_ERR_CRCERR;
	else if(msc_sta & MSC_STA_TOER)
		return MSP_ERR_TIMEOUT;
	else if(msc_sta & MSC_STA_RDY)
		return MSP_NOERROR;
	if(gMSDC_Handle.is_timeout)
		return MSDC_GPT_TIMEOUT_ERR;
	return MSP_NOERROR;
}
/*************************************************************************
* FUNCTION
*  MSP_WaitCard_INT
*
* DESCRIPTION
*	wait for MS card producing INT signal and retreive result of the INT
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
static MSP_STATUS MSP_WaitCard_INT(kal_uint16 *msc_sta)
{
#ifdef MSDC_USE_INT	
	kal_uint32 flags;

	MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_CMD);
	kal_retrieve_eg_events(MSDC_Events,EVENT_MSIFIRQ,KAL_AND_CONSUME,&flags,KAL_SUSPEND);	
	MSDC_STOP_TIMER();
	*msc_sta = *(volatile kal_uint16*)MSC_STA;
#else	
		kal_uint32 t1;

		t1 = drv_get_current_time();
		MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_DAT);
		while(!((*msc_sta = *(volatile kal_uint16*)MSC_STA)&MSC_STA_SIF)
			&& MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
		{
			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
				gMSDC_Handle.is_timeout = KAL_TRUE;
		}
		MSDC_STOP_TIMER();
		MSDC_CLR_INT();	
		if((*msc_sta = *(volatile kal_uint16*)MSC_STA)&MSC_STA_SIF)
			return MSP_NOERROR;
		if(gMSDC_Handle.is_timeout)
			return MSDC_GPT_TIMEOUT_ERR;
#endif
	if(gMSP.mode == MSP_SERIAL)
	{	
		MSP_STATUS status;
		kal_uint8 reg[4];
		
		status = MSP_TPC_GetInt((kal_uint32*)reg);
		if(reg[0] & INT_BREQ)
			*msc_sta |= MSC_STA_BREQ;
		if(reg[0] & INT_CED)
			*msc_sta |= MSC_STA_CED;
		if(reg[0]& INT_CMDNK)
			*msc_sta |= MSC_STA_CMDNK;
		if((reg[0] & INT_ERR) || (status != MSP_NOERROR))
			*msc_sta |= MSC_STA_ERR;
	}	
	return MSP_NOERROR;
}
/*************************************************************************
* FUNCTION
*  MSP_TPCs
*
* DESCRIPTION
*	send TPC with data transfer 
*
* PARAMETERS
*	buffer: data buffer for read or write
*	size: size of data to read or write(bytes)
*	tpc: TPC code
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*
*************************************************************************/
static MSP_STATUS MSP_TPCs(kal_uint32* buffer, kal_uint16 size, kal_uint8 tpc)
{
	MSP_STATUS status;
	kal_uint32 i, count;
	kal_bool IsWrite;
	
	// check handshake ready produced by card
	//direction 0: read, 1: write
	IsWrite = (tpc & 0x8)?KAL_TRUE:KAL_FALSE;
	
	// data transfer
	if(size == 512)
	{
		EnableMSDC_DMA();
		MSDC_DMATransferFirst((kal_uint32)buffer,512/4,IsWrite);						
		// send TPC
		MSP_SendTPC(tpc,size);
		status = MSDC_DMATransferFinal();
		status = MSP_WaitCmdRdyOrTo();		
		DisableMSDC_DMA();
		if(status != MSP_NOERROR)
			goto err_exit; // maybe timeout, crc err.			
	}	
	else
	{		
		kal_uint32 t1;
		
		MSP_SendTPC(tpc,size);
		count = (size+3)/4;

		t1 = drv_get_current_time();		
		if(!IsWrite)	// read
		{	
			for(i=0;i<count;)
			{
				if(!MSDC_IS_FIFO_EMPTY)
				{
					*(buffer+i) = *(volatile kal_uint32*)MSDC_DAT;
					i++;
				} 
				else if(MS_IS_TIMEOUT)
					break;				
				else if(!gMSDC_Handle.mIsPresent)
					break;
				if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
				{					
					gMSDC_Handle.is_timeout = KAL_TRUE;
					return MSDC_GPT_TIMEOUT_ERR;
					
				}
			}
		}
		else	// write
		{
			for(i=0;i<count;)
			{
				if(!MSDC_IS_FIFO_FULL)
				{
					*(volatile kal_uint32*)MSDC_DAT = *(buffer+i);
					i++;
				}
				else if(MS_IS_TIMEOUT)
					break;				
				else if(!gMSDC_Handle.mIsPresent)
					break;	
				if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
				{					
					gMSDC_Handle.is_timeout = KAL_TRUE;
					return MSDC_GPT_TIMEOUT_ERR;
					
				}				
			}
			// wait cmd ready or busy timeout
		}
		if((status = MSP_WaitCmdRdyOrTo()) != MSP_NOERROR)
			return status;
			
	}
	return MSP_NOERROR;
	
err_exit:
	#if defined(MSDC_USE_INT)
	kal_set_eg_events(MSDC_Events,0,KAL_AND);
	#endif
	DisableMSDC_DMA();
	MSP_CMD_Stop();
	return status;
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_ReadLongData
*
* DESCRIPTION
*	read data form pagebuffer in uints of page(512 bytes)
*
* PARAMETERS
*	rxbuffer: data buffer for read 
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*
*************************************************************************/
static MSP_STATUS MSP_TPC_ReadLongData(kal_uint32* rxbuffer)
{	
	return MSP_TPCs(rxbuffer,512,TPC_READ_LONG_DATA);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_WriteLongData
*
* DESCRIPTION
*	write data to pagebuffer in uints of page(512 bytes)
*
* PARAMETERS
*	txbuffer: data buffer for read 
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/
// TPC for writing to PageBuffer in uints of page(512 bytes)
MSP_STATUS MSP_TPC_WriteLongData(kal_uint32* txbuffer)
{
	return MSP_TPCs(txbuffer,512,TPC_WRITE_LONG_DATA);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_ReadReg
*
* DESCRIPTION
*	TPC for reading form the register which address was set by TPC_SET_R/W_REG_ADRS.
*
* PARAMETERS
*	buffer: data buffer for read 
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
* 	Note: buffer must be prepared up to multiple of 4 ,ex.
* 	if length  = 7 , u must prepare 8 bytes  = 2x4 bytes as buffer 
*
*************************************************************************/
static MSP_STATUS MSP_TPC_ReadReg(kal_uint32* buffer, kal_uint8 length)
{
	return 	MSP_TPCs(buffer,(kal_uint16)length,TPC_READ_REG);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_WriteReg
*
* DESCRIPTION
*	TPC for writing data into the register which address was set by TPC_SET_R/W_REG_ADRS.
*
* PARAMETERS
*	buffer: data buffer for write 
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
* 	Note: buffer must be prepared up to multiple of 4 ,ex.
* 	if length  = 7 , u must prepare 8 bytes  = 2x4 bytes as buffer 
*
*************************************************************************/
static MSP_STATUS MSP_TPC_WriteReg(kal_uint32* buffer, kal_uint8 length)
{
	return 	MSP_TPCs(buffer,(kal_uint16)length,TPC_WRITE_REG);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_SetRWAdrs
*
* DESCRIPTION
*	TPC for setting values which determine the registers accessed by WRITE_REG and READ_REG
*
* PARAMETERS
*	r_adrs: start address of register for ReadReg
*	r_len: length for ReadReg
*	w_adrs: start address of register for WriteReg
*	w_len: length for WriteReg
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
static MSP_STATUS MSP_TPC_SetRWAdrs(kal_uint8 r_adrs, kal_uint8 r_len, kal_uint8 w_adrs, kal_uint8 w_len)
{
	kal_uint8 data[4];

	data[0] = r_adrs;
	data[1] = r_len;
	data[2] = w_adrs;
	data[3] = w_len;

	return 	MSP_TPCs((kal_uint32*)data,(kal_uint16)4,TPC_SET_R_W_REG_ADRS);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_GetInt
*
* DESCRIPTION
*	TPC for read 1 byte INT register
*
* PARAMETERS
*	intreg: intreg contains the result of the INT register
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
static MSP_STATUS MSP_TPC_GetInt(kal_uint32* intreg)
{
	return 	MSP_TPCs(intreg,(kal_uint16)1,TPC_GET_INT);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_ReadShortData
*
* DESCRIPTION
*	read data from data buffer in the size of (32, 64, 128 and 256 bytes)
*
* PARAMETERS
*	buffer: data buffer for read
*	length: enum of short data (32,64,128,256)
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
// read data from data buffer in the size of (32, 64, 128 and 256 bytes)
static MSP_STATUS MSP_TPC_ReadShortData(kal_uint32* buffer, ms_ShortData_enum length)
{
	// set TPC parameter for short data length
	MSP_TPC_SetRWAdrs(0,8,MSP_TPCPARA_REG,1);
	MSP_TPC_WriteReg((kal_uint32*)&length,1);
	
	return 	MSP_TPCs(buffer,(kal_uint16)(1 << (length+5)),TPC_READ_SHORT_DATA);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_WriteShortData
*
* DESCRIPTION
*	write data into data buffer in the size of (32, 64, 128 and 256 bytes)
*
* PARAMETERS
*	buffer: data buffer for write
*	length: enum of short data (32,64,128,256)
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
MSP_STATUS MSP_TPC_WriteShortData(kal_uint32* buffer, ms_ShortData_enum length)
{
	// set TPC parameter for short data length
	MSP_TPC_SetRWAdrs(0,8,MSP_TPCPARA_REG,1);
	MSP_TPC_WriteReg((kal_uint32*)&length,1);
		
	return 	MSP_TPCs(buffer,(kal_uint16)length,TPC_WRITE_SHORT_DATA);
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_SetCmd
*
* DESCRIPTION
*	send command to be executed by Memory I/F Sequencer
*
* PARAMETERS
*	cmd: command code
*	msc_stc: status after command is executed 
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
MSP_STATUS MSP_TPC_SetCmd(kal_uint8 cmd, kal_uint16* msc_sta)
{
	MSP_STATUS status;

	// send the TPC (1 bytes data)
	MSP_SendTPC(TPC_SET_CMD,1);
	// write 1 byte data into fifo
	*(volatile kal_uint8*)MSDC_DAT = cmd;
	// TPC transaction complete
	if((status = MSP_WaitCmdRdyOrTo()) != MSP_NOERROR)
		return status;			
	// wait for INT signal
	MSP_WaitCard_INT(msc_sta);
	// cmd not accept
	if(*msc_sta & (MSC_STA_CMDNK|MSC_STA_ERR))
		return MSP_ERR_CMDFAIL;

	return MSP_NOERROR;	
}
/*************************************************************************
* FUNCTION
*  MSP_TPC_ExSetCmd
*
* DESCRIPTION
*	send command with data count and address to Memory I/F Sequencer
*
* PARAMETERS
*	adrs: start address for data 
*	count: data count
*	cmd: command code
*	msc_sta: status after command is executed
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
static MSP_STATUS MSP_TPC_ExSetCmd(kal_uint32 adrs, kal_uint16 count, kal_uint8 cmd, kal_uint16* msc_sta)
{
	MSP_STATUS status;
	kal_uint8 buffer[8] = {0};
	
	// set parameter register (7 bytes = cmd x1 + count x2 + adrs x4 )
	buffer[0] = cmd;
	buffer[1] = count >> 8;
	buffer[2] = (kal_uint8)count;
	buffer[3] = adrs >> 24;
	buffer[4] = adrs >> 16;
	buffer[5] = adrs >> 8;
	buffer[6] = (kal_uint8)adrs;
	
	if((status = MSP_TPCs((kal_uint32*)buffer,7,TPC_EX_SET_CMD)) != MSP_NOERROR)
		return status;

	// wait for INT signal
	MSP_WaitCard_INT(msc_sta);
	// cmd not accept
	if(*msc_sta & (MSC_STA_CMDNK|MSC_STA_ERR))
		return MSP_ERR_CMDFAIL;

	return MSP_NOERROR;	
}
/*************************************************************************
* FUNCTION
*  MSP_CMD_ReadWriteData
*
* DESCRIPTION
*  read/write data in user area sequentially starting from the designated address.
*
* PARAMETERS
*	1. adrs: start address.
*	2. count: number of of sectors
*	3. buffer: data buffer 
*	4. sectors: actually sectors accessed 
*	5. IsWrite: indicating read or write data
*
* RETURNS
*	MSP_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
*
*************************************************************************/
MSP_STATUS MSP_CMD_ReadWriteData(kal_uint32 adrs, kal_uint16 count, kal_uint32* buffer, kal_uint16* sectors,msp_direction_enum IsWrite)
{
	MSP_STATUS status;
	kal_uint16 msc_sta;
	kal_uint8	cmd,tpc;
	
	*sectors = 0;
	if(IsWrite == MSP_WRITE)
	{
		if(gMSP.is_wp)
			return MSP_ERR_WRITE_PROTECT;
		cmd = CMD_WRITE_DATA;
		tpc = TPC_WRITE_LONG_DATA;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -