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

📄 sd_disk.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	if (error)
	{
		RETAILMSG(MSG_DISK, (_T("SD: SDI_ResetInterface - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return	FALSE;
	}
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Deinit interface - deinit the current device
//
// Arguments:
//		controller - handle for the instance.
//		errorcode - record error. 
//
// Functions: 
//		Realese DMA and close the interrupt event. 
//
//------------------------------------------------------------------------------
BOOL 
SDI_DeinitInterface(
	SD_controller *controller, 
	unsigned long *errorcode
	)
{
	unsigned long error = 0;
	if (!controller)
		error = 1;
	if (!error)
	{
		SDI_ResetInterface(controller, 0);
		if (controller->Registers)
			MmUnmapIoSpace((void*)controller->Registers, sizeof(SD_REG));
		if (controller->InterruptEvent)
			CloseHandle(controller->InterruptEvent);
		if (controller->SysDetect)
			MmUnmapIoSpace((void*)controller->SysDetect, sizeof(SD_REG));
	}
	if (!error)
	{
		SDI_ReleaseDMA();
		if (DMAIntrEvent != NULL)
		{
			CloseHandle (DMAIntrEvent);
			DMAIntrEvent = NULL;
		}
	}
	if (error)
	{
		RETAILMSG(MSG_DISK, (_T("SD: SDI_DeinitInterface - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return	FALSE;
	}
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Send Command
//
// Arguments:
//		controller - handle for the instance.
//		param - parameters of command.
//		arg - arguments of command.
//		response - return values if the command has response, or else ignored.
//		errorcode - record error. 
//
// Functions:
//		Send command to card. Then wait the interrupt. 
//		If the command has response, it will feed back response. Else it will 
//		send a command end signal. 
//		See also define of CommandParameters. 
//
//------------------------------------------------------------------------------
BOOL 
SDI_SendCmd(
	SD_controller*controller, 
	const Command_Parameter *param, 
	unsigned long arg, 
	apMCI_sResponse *response, 
	unsigned long *errorcode
	)
{
	unsigned long error = 0;
	unsigned long CommandData = 0;
	BOOL TimeOut = FALSE;
	SD_REG *regs;
	if (!controller || !param)
		error = 1;
	regs = controller->Registers;
	if (!regs)
		error = 2;
	if (!error)
	{
		BOOL cmdok = FALSE;
		regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;
		/*construct command*/
		apBIT_SET(CommandData,MCI_CMD_INDEX, param->CmdIndex);
		apBIT_SET(CommandData,MCI_CMD_RESPONSE, param->Responsetype);
		apBIT_SET(CommandData,MCI_CMD_INTERRUPT, param->CmdTimer);
		apBIT_SET(CommandData,MCI_CMD_PENDING, (param->Option & MCI_CMDOPT_PENDING)!=0);
		/*enable bit*/
		CommandData |= apBIT_MASK(MCI_CMD_ENABLE);
	
		regs->sd_MASK0 = 0;
		InterruptDone(SYSINTR_SD0);
		regs->sd_MASK0 = param->InterruptMask;
		regs->sd_ARGUMENT = arg ; 
		ResetEvent(controller->InterruptEvent);
		regs->sd_COMMAND  = CommandData;
		while (!error && !cmdok)
		{
			if (WaitForSingleObject(controller->InterruptEvent, param->WaitTime) == WAIT_TIMEOUT)
			{
				error = 3;
				InterruptDone(SYSINTR_SD0);
			}
			else
			{
				unsigned long LastStatus = regs->sd_STATUS&param->InterruptMask;
				if (((LastStatus&apMCI_CMDSTAT_SENT) && (param->Responsetype == apMCI_CMDRESP_NONE)) || 
					((LastStatus&apMCI_CMDSTAT_RESPOK) && (param->Responsetype != apMCI_CMDRESP_NONE)))
				{
					cmdok = TRUE;
				}
				else if (LastStatus & apMCI_CMDSTAT_FAIL)
				{
					RETAILMSG(MSG_DISK, (_T("SD: SDI_SendCmd -Command:0x%x Status:0x%x\r\n"), CommandData, LastStatus));
					error = 4;
				}
				regs->sd_CLEAR = LastStatus;
				InterruptDone(SYSINTR_SD0);
			}
		}
		regs->sd_MASK0 = 0;
		regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;
		regs->sd_COMMAND  = 0;
		regs->sd_ARGUMENT = apBITS_ALL; 
	}
	if (response && (param->Responsetype!=apMCI_CMDRESP_NONE))
	{
		if (param->Responsetype == apMCI_CMDRESP_SHORT)
			response->ShortResponse = regs->sd_RESP0;
		else if (param->Responsetype == apMCI_CMDRESP_LONG)
		{
			response->LongResponse[0] = regs->sd_RESP0;
			response->LongResponse[1] = regs->sd_RESP1;
			response->LongResponse[2] = regs->sd_RESP2;
			response->LongResponse[3] = regs->sd_RESP3;
		}
	}
	if (error)
	{
		RETAILMSG(MSG_DISK, (_T("SD: SDI_SendCmd - error:0x%x\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return	FALSE;
	}
	return TRUE;
}


//------------------------------------------------------------------------------
//
// Decode long response
//
// Arguments:
//		pLongResponse - Pointer to a long response structure. 
//		LowestBit - Lowest bit to decode. 
//		BitWidth - How many bits to decode. 
//
// Functions:
//		Intercept a segment in the long response. 
//
//------------------------------------------------------------------------------
unsigned long 
SDI_PrvLongResponseDecode(
	apMCI_sResponse *pLongResponse,
	unsigned long LowestBit,
	unsigned long BitWidth
	)
{
	unsigned long Result;
	unsigned long LowWordBits;		// bits in the low word 
	
//	RETAILMSG(MSG_DISK, (_T("SD: SDI_PrvLongResponseDecode+\r\n")));
	// The low bits are in the last words of the response, so bit B lies in word 4-(B/32)
	LowWordBits=32 - (LowestBit & 31);
	Result=apBIT_GET_FIELD(
		pLongResponse->LongResponse[3-(LowestBit>>5)],
		MIN(BitWidth,LowWordBits),
		LowestBit & 31
		);
	// Go to the next word and take some low bits from there
	if (BitWidth > LowWordBits)
	{
		Result|=apBIT_GET_FIELD(
			pLongResponse->LongResponse[2-(LowestBit>>5)],
			BitWidth - LowWordBits,
			0
			)<<LowWordBits;
	}
//	RETAILMSG(MSG_DISK, (_T("SD: SDI_PrvLongResponseDecode-\r\n")));
	return Result;                                   
}

//------------------------------------------------------------------------------
//
// Get card identification data
//
// Arguments:
//		controller - handle for the instance.
//		pDecodedResponse - pointer to decode respond. 
//		errorcode - record error. 
//
//------------------------------------------------------------------------------
BOOL 
SDI_GetCID(
	SD_controller *controller, 
	apMCI_sDecodedCID *pDecodedResponse, 
	unsigned long *errorcode
	)
{
	apMCI_sResponse  response, *pResponseData = &response;
	unsigned long temp1, temp2, error = 0;

	RETAILMSG(MSG_DISK, (_T("SD: SDI_GetCID+\r\n")));
	if (!controller || !pDecodedResponse)
		error = 1;
	if (!error)
	{
		if (!SDI_SendCmd(controller, &CommandParameters[ALL_SEND_CID], 0x0, &response, &error))
		{
			if (!SDI_SendCmd(controller, &CommandParameters[ALL_SEND_CID], 0x0, &response, &error))
			{
				error = 2;
			}
		}
	}
	if (!error)
	{
		pDecodedResponse->MID=
			SDI_PrvLongResponseDecode(pResponseData,bsMCI_CID_MID,bwMCI_CID_MID);
		// get Application ID
		pDecodedResponse->OID=
			SDI_PrvLongResponseDecode(pResponseData,bsMCI_CID_OID,bwMCI_CID_OID);
		
		temp1 = SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PNM_H,bwMCI_SD_CID_PNM_H);
		temp2 = SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PNM_L,bwMCI_SD_CID_PNM_L);
		
		pDecodedResponse->PNM[0] = (unsigned char)apBIT_GET_FIELD(temp1, 8, 0);
		pDecodedResponse->PNM[1] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 24);
		pDecodedResponse->PNM[2] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 16);
		pDecodedResponse->PNM[3] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 8);
		pDecodedResponse->PNM[4] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 0);
		pDecodedResponse->PNM[5] = 0;
		pDecodedResponse->PNM[6] = 0;
		
		// get Product Revision
		pDecodedResponse->PRV=
			SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PRV,bwMCI_SD_CID_PRV);
		// get Product Serial Number
		pDecodedResponse->PSN=
			SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PSN,bwMCI_SD_CID_PSN);
		// get Manufacturing Date
		pDecodedResponse->MDT=
			SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_MDT,bwMCI_SD_CID_MDT);
	}
	
	if (error)
	{
		RETAILMSG(MSG_DISK, (_T("SD: SDI_GetCID - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return	FALSE;
	}
	RETAILMSG(MSG_DISK, (_T("SD: SDI_GetCID-\r\n")));
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Get card specific data
//
// Arguments:
//		controller - handle for the instance.
//		pDecodedResponse - pointer to decode respond. 
//		errorcode - record error. 
//
//------------------------------------------------------------------------------
BOOL SDI_GetCSD(
	SD_controller *controller, 
	apMCI_sDecodedCSD *pDecodedResponse, 
	unsigned long RCA,
	unsigned long *errorcode
	)
{
	unsigned long error = 0;
	/* look up tables for calculating values in CSD register */
	static const unsigned long TAACUnit[8] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000}; /* calculates as 0.1ns */
	static const unsigned long TranSpeedUnit[8] = {10, 100, 1000, 10000, 0, 0, 0, 0};              /* calculates as kHz */
	static const unsigned long Value[16] = {0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80};
		
	apMCI_sResponse  response, *pResponseData = &response;
	if (!controller || !pDecodedResponse)
		error = 1;
	if (!error)
	{
		if (!SDI_SendCmd(controller, &CommandParameters[SEND_CSD], RCA, &response, &error))
		{
			if (!SDI_SendCmd(controller, &CommandParameters[SEND_CSD], RCA, &response, &error))
			{
				error = 2;
			}
		}
	}
	if (!error)
	{
		pDecodedResponse->csd_structure = (unsigned char)SDI_PrvLongResponseDecode(pResponseData, bsMCI_CSD_STRUCTURE, bwMCI_CSD_STRUCTURE);
		pDecodedResponse->crc = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CRC, bwMCI_CSD_CRC);
		pDecodedResponse->file_format = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_FILE_FORMAT, bwMCI_CSD_FILE_FORMAT);
		pDecodedResponse->temporary_write_protection = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_TEMP_WP, bwMCI_CSD_TEMP_WP);
		pDecodedResponse->permanent_write_protection = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_PERM_WP, bwMCI_CSD_PERM_WP);
		pDecodedResponse->copy_flag = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_COPY, bwMCI_CSD_COPY);
		pDecodedResponse->file_format_group = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_FILE_FORMAT_GRP, bwMCI_CSD_FILE_FORMAT_GRP);
		if (pDecodedResponse->csd_structure == 0)
		{
			pDecodedResponse->erase_sector_size = 1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_SECT_SD, bwMCI_CSD_ERASE_SECT_SD);
		}
		else
		{
			pDecodedResponse->erase_sector_size = (1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_GRP_SIZE11, bwMCI_CSD_ERASE_GRP_SIZE11))
				* (1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_GRP_MULT11, bwMCI_CSD_ERASE_GRP_MULT11));
		}
		
		if (pDecodedResponse->csd_structure == 0)
		{
			pDecodedResponse->write_protect_group_size = 1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WP_GRP_SIZE, bwMCI_CSD_WP_GRP_SIZE);
		}
		else
		{
			pDecodedResponse->write_protect_group_size = 1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WP_GRP_SIZE11, bwMCI_CSD_WP_GRP_SIZE11);
		}
    
		pDecodedResponse->partial_blocks_for_write_allowed = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WTBLP, bwMCI_CSD_WTBLP);
		pDecodedResponse->max_write_data_block_length = 1 << SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WTBL, bwMCI_CSD_WTBL);
		pDecodedResponse->write_speed_factor = 1 << SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_R2W, bwMCI_CSD_R2W);
		pDecodedResponse->write_protect_group_enable = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WP_GRP_ENABLE, bwMCI_CSD_WP_GRP_ENABLE);
		pDecodedResponse->erase_single_block_enable = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_SINGLE_BLOCK_ENABLE, bwMCI_CSD_ERASE_SINGLE_BLOCK_ENABLE);
		pDecodedResponse->device_size_multiplier = 1 << (2 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CMULT, bwMCI_CSD_CMULT));
		pDecodedResponse->max_write_current_max = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_W_CURR_MAX, bwMCI_CSD_VDD_W_CURR_MAX);
		pDecodedResponse->max_write_current_min = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_W_CURR_MIN, bwMCI_CSD_VDD_W_CURR_MIN);
		pDecodedResponse->max_read_current_max = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_R_CURR_MAX, bwMCI_CSD_VDD_R_CURR_MAX);
		pDecodedResponse->max_read_current_min = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_R_CURR_MIN, bwMCI_CSD_VDD_R_CURR_MIN);
		pDecodedResponse->device_size = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CSIZE, bwMCI_CSD_CSIZE);
		pDecodedResponse->dsr_implemented = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_DSR_IMP, bwMCI_CSD_DSR_IMP);
		pDecodedResponse->read_block_misalignment = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_RDBLMIS, bwMCI_CSD_RDBLMIS);
		pDecodedResponse->write_block_misalignment = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WTBLMIS, bwMCI_CSD_WTBLMIS);
		pDecodedResponse->partial_blocks_for_read_allowed = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_RDBLP, bwMCI_CSD_RDBLP);
		pDecodedResponse->max_read_data_block_length = 1 << SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_RDBL, bwMCI_CSD_RDBL);
		pDecodedResponse->card_command_classes = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CCC, bwMCI_CSD_CCC);
		pDecodedResponse->max_data_transfer_rate_khz = TranSpeedUnit[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_MAXTRANLO, bwMCI_CSD_MAXTRANLO)]
			* Value[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_MAXTRANHI, bwMCI_CSD_MAXTRANHI)];
		pDecodedResponse->data_read_access_time_2_in_clk_cycles = 100 * SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_NSAC, bwMCI_CSD_NSAC);
		
		pDecodedResponse->data_read_access_time_1_tns = TAACUnit[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_TAACLO, bwMCI_CSD_TAACLO)]
			* Value[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_TAACHI, bwMCI_CSD_TAACHI)];
		
		pDecodedResponse->CardSize = (pDecodedResponse->device_size + 1)
			*  pDecodedResponse->device_size_multiplier
			*  pDecodedResponse->max_read_data_block_length;
	}
	if (error)
	{
		RETAILMSG(MSG_DISK, (_T("SD: SDI_GetCSD - error:%d\r\n"), error));
		if (errorcode)
			*errorcode = error;
		return	FALSE;
	}
	return TRUE;
}

⌨️ 快捷键说明

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