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

📄 sdregb.c

📁 ssd192Xv1 液晶驱动程序 驱动程序 彩屏液晶
💻 C
📖 第 1 页 / 共 5 页
字号:
	} else {
		db ("sdhc_init: Read SCR skipped (MMC)\n");
		if (sdhc_card_select (g_rca, 1) < 0)			return -1;

	}
	return 0;
}


int sdhc_reset (unsigned char reset_type){
	int i = 0;

	SSD_REGWB(REG_u8SwReset, SSD_REGRB(REG_u8SwReset)| reset_type);	for (i = 0; i < MAX_WAIT; i++)
	{
		if (!(SSD_REGRB(REG_u8SwReset) & reset_type))			break;
	}

	return (i == MAX_WAIT) ? -1 : 0;
}

int send_cmd (		unsigned short idx, 
		unsigned short type, 
		unsigned short rsp, 
		int data_prsnt,
		int crc_check, 
		int idx_check, 
		unsigned long arg[4])
{
//	debug("%s(sdhc=0x%x,idx%d,type%d,resp%d,data_prsnt%d,crc_check%d,idx_check%d,arg[4])\n",__FUNCTION__,sdhc,idx, type, rsp, data_prsnt, crc_check, idx_check);
//	debug("arg[0-3]=0x%x, 0x%x, 0x%x, 0x%x\n",arg[0],arg[1],arg[2],arg[3]);

	int i;
	int psr_inhibit_dat = 0;
	int error = 0;
	unsigned short cmd = 0;
	unsigned short u16NrmIntrSignalEn = 0;
	unsigned short u16ErrIntrSignalEn = 0;

	if (type == SUSPEND || type == RESUME)
	{
		db ("send_cmd: Suspend/Resume are not supported\n");
		return -1;
	}

	if (SSD_REGRL(REG_u32PrsntState) & PSR_INHIBIT_CMD)	{
		db ("send_cmd (CMD%u): Command Inhibit CMD is active\n", idx);
		return -1;
	}

	if (rsp == R48b || data_prsnt)
	{
		SSD_REGWB(REG_u8ToutCntl, 0x0e);	// TMCLK * 2^^27	}

	if (!g_irq) {
		// this has nothing to do with interrupts enabling control
		u16NrmIntrSignalEn = SSD_REGRW(REG_u16NrmIntrSignalEn);		u16ErrIntrSignalEn = SSD_REGRW(REG_u16ErrIntrSignalEn);		SSD_REGWW(REG_u16NrmIntrSignalEn, 0);		// turn off any irqs, send command is done synchronously		SSD_REGWW(REG_u16ErrIntrSignalEn,0);		// turn off any irqs	}

	// clear previous status
	SSD_REGWW(REG_u16NrmIntrStatus , (INTR_CMD_COMPLETE | (data_prsnt ? INTR_DAT_COMPLETE : 0)));		SSD_REGWW(REG_u16NrmIntrStatusEn ,	SSD_REGRW(REG_u16NrmIntrStatusEn)| (INTR_CMD_COMPLETE | (data_prsnt ? INTR_DAT_COMPLETE : 0)));		SSD_REGWW(REG_u16ErrIntrStatus, SSD_REGRW(REG_u16ErrIntrStatus));	// clear previous status	SSD_REGWW(REG_u16ErrIntrStatusEn ,			SSD_REGRW(REG_u16ErrIntrStatusEn)| 			EINTR_CMD_TOUT | EINTR_CMD_END |			(crc_check ? EINTR_CMD_CRC : 0) | 
			(idx_check ? EINTR_CMD_IDX : 0) |
		       	(data_prsnt ? (EINTR_DAT_TOUT | EINTR_DAT_CRC | EINTR_DAT_END |
				       EINTR_VS_DAT_CONFLICT | EINTR_VS_BLKSZ_ERR) : 0) |
			((rsp == R48b) ? EINTR_DAT_TOUT : 0) 			| EINTR_VS_RSP_DIR );
	SSD_REGWL(REG_u32Arg, SWAP32(arg[0]));	cmd |= CMD_IDX (idx) | 
		CMD_TYPE (type) | 
		CMD_RSP (rsp) |
		(crc_check ? CMDR_CRC_CHECK_EN : 0) | 
		(idx_check ? CMDR_IDX_CHECK_EN : 0) |
		(data_prsnt ? CMDR_DATA_PRESENT : 0);

//	db ("send_cmd (CMD%u): Present State Register (0x%08lx)\n", idx, SWAP32(sdhc->REG_u32PrsntState));	SSD_REGWW(REG_u16Cmd , cmd);
	for (i = 0; i < MAX_WAIT; i++) {
		if ((SSD_REGRL(REG_u32PrsntState) & PSR_INHIBIT_CMD) 		 || (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_CMD_COMPLETE))			break;
	}

	if (i == MAX_WAIT)
	{
		db ("send_cmd (CMD%u): Command Inhibit (CMD) not set NISR=0x%04x, PSR=0x%08lx, test failed\n", idx, 
			SWAP16 (SSD_REGRW(REG_u16NrmIntrStatus)), SWAP32(SSD_REGRL(REG_u32PrsntState)));		error = -1;
		goto l_err;
	}
#if 0
	db ("send_cmd (CMD%u): Command Inhibit (CMD) set\n", idx);
	db ("send_cmd (CMD%u): Waiting for Command Complete Status\n", idx);
#endif

	for (i = 0; i < MAX_WAIT; i++)
	{
		if (SSD_REGRW(REG_u32PrsntState) & PSR_INHIBIT_DAT)			psr_inhibit_dat = 1;
		if (SSD_REGRW(REG_u16NrmIntrStatus) & (INTR_CMD_COMPLETE | INTR_ERR))				break;
//		delay_us (1);
	}

	arg[0] = SWAP32 (SSD_REGRL(REG_a32Rsp+0));	arg[1] = SWAP32 (SSD_REGRL(REG_a32Rsp+4));	arg[2] = SWAP32 (SSD_REGRL(REG_a32Rsp+8));	arg[3] = SWAP32 (SSD_REGRL(REG_a32Rsp+12));
	if (g_verbose)
	{
		db ("send_cmd (CMD%u): NISR (0x%04x), NISREN (0x%04x)\n", idx, 
			SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16NrmIntrStatusEn)) );		db ("send_cmd (CMD%u): EISR (0x%04x), EISREN (0x%04x)\n", idx, 
			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatusEn)));		db ("send_cmd (CMD%u): (After Command Complete) Present State Register (0x%08lx)\n", 
			idx, SWAP32(SSD_REGRL(REG_u32PrsntState)));		db ("send_cmd (CMD%u): RSP[127..0] = 0x%08lx %08lx %08lx %08lx\n", idx, 
			arg[3], arg[2], arg[1], arg[0]);
	}

	if (i == MAX_WAIT)
	{
		db ("send_cmd (CMD%u): Timeout waiting for Command Complete\n", idx);
		error = 1;
		goto l_err;
	}

	if (rsp == R48b)
	{
		if (SSD_REGRL(REG_u32PrsntState) & PSR_INHIBIT_DAT)			db ("send_cmd (CMD%u): Busy detection in progress\n", idx);
		else
			db ("send_cmd (CMD%u): NO busy detection in progress\n", idx);

		for (i = 0; i < MAX_WAIT; i++)
		{
			if (SSD_REGRW(REG_u16NrmIntrStatus) & (INTR_DAT_COMPLETE | INTR_ERR))				break;
			delay_us (1);
		}

		if (i == MAX_WAIT)
		{
			db ("send_cmd (CMD%u): PSR = 0x%08lx\n", idx, SWAP32(SSD_REGRL(REG_u32PrsntState)));			db ("send_cmd (CMD%u): Timeout waiting for Transfer Complete\n", idx);
			error = 1;
			goto l_err;
		}
	}

	if (rsp == R48b && (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_DAT_COMPLETE) && 		(SSD_REGRW(REG_u16ErrIntrStatus) & EINTR_DAT_TOUT))	{
		db ("send_cmd (CMD%u): Transfer Complete occured together with Busy end timeout\n", idx);
		SSD_REGWW(REG_u16ErrIntrStatus , EINTR_DAT_TOUT);	}

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)	{
		db ("send_cmd (CMD%u): Command resulted in Error, NISR (0x%04x), EISR(0x%04x)\n", 
			idx, SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));		SSD_REGWW(REG_u16ErrIntrStatus , SSD_REGRW(REG_u16ErrIntrStatus));		if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)		{
			db ("send_cmd (CMD%u): NISR.INTR_ERR(b15) could not be cleared. "
				"NISR (0x%04x), EISR (0x%04x)\n",
				idx, SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));		}

		SSD_REGWW(REG_u16NrmIntrStatus , INTR_CMD_COMPLETE);		if (SSD_REGRW(REG_u16NrmIntrStatus))		{
			db ("send_cmd (CMD%u): NISR (0x%04x) -> bits are still set in NISR\n",
				idx, SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)));			SSD_REGWW(REG_u16NrmIntrStatus , SSD_REGRW(REG_u16NrmIntrStatus));		}
		error = 1;
		goto l_err;
	}

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_CMD_COMPLETE)	{
		SSD_REGWW(REG_u16NrmIntrStatus , INTR_CMD_COMPLETE);		if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_CMD_COMPLETE)		{
			db ("send_cmd (CMD%u): NISR.INTR_CMD_COMPLETE(b0) could not be cleared. "
				"NISR (0x%04x), EISR (0x%04x). Trying again!\n", 
				idx, SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));			SSD_REGWW(REG_u16NrmIntrStatus , INTR_CMD_COMPLETE);			if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_CMD_COMPLETE)				error = 1;
			else {
				db ("send_cmd: 2nd time success\n");
			}
		} 
#if 0
		// commented off - by Sree, since PSR_INHIBIT_DAT has already been checked for previously and 
		// can toggle back to 0 once data transmission is complete. 
		if (data_prsnt && !(SSD_REGWL(REG_u32PrsntState & PSR_INHIBIT_DAT))		{
			db ("send_cmd (CMD%u): Data Present but PSR_INHIBIT_DAT is NOT set\n",
				idx);
			error = 1;
		}
#endif
	}

	if (rsp == R48b)
	{ 
		for (i = 0; i < MAX_WAIT; i++) {
			if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_DAT_COMPLETE) {				SSD_REGWW(REG_u16NrmIntrStatus , INTR_DAT_COMPLETE);				if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_DAT_COMPLETE) {					db ("send_cmd (CMD%u): NISR.INTR_DAT_COMPLETE(b0) could not be cleared. "
						"NISR (0x%04x), EISR (0x%04x)\n", 
						idx, SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));					error = 1;
				}
				break;

			}
			delay_us (1);
		}

		if (i == MAX_WAIT) {
			db ("send_cmd (CMD%u): SW TOUT: R48b but no INTR_DAT_COMPLETE, NISR(0x%04x)\n",
				idx, SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)));			error = 1;
		}
		if (error)
			goto l_err;
	}
l_err:
	SSD_REGWW(REG_u16NrmIntrStatusEn, SSD_REGRW(REG_u16NrmIntrStatusEn)& ~INTR_CMD_COMPLETE);	SSD_REGWW(REG_u16ErrIntrStatusEn, SSD_REGRW(REG_u16ErrIntrStatusEn) & ~(EINTR_CMD_TOUT | EINTR_CMD_CRC | EINTR_CMD_IDX | EINTR_CMD_END | EINTR_VS_RSP_DIR));
	if (error || g_verbose)
		db ("send_cmd (CMD%u): Result = %s\n", idx, (error ? "Failed": "Passed"));

	// should be protected from interrupts
	if (!g_irq) {
		SSD_REGWW(REG_u16NrmIntrSignalEn , u16NrmIntrSignalEn);		SSD_REGWW(REG_u16ErrIntrSignalEn , u16ErrIntrSignalEn);	}

	return (error ? -1 : 0);
}

int send_app_cmd (		unsigned short idx, 
		unsigned short type, 
		unsigned short rsp, 
		int crc_check, 
		int idx_check, 
		unsigned long arg[4])
{
	int i;

	int error = 0;
	unsigned short cmd;
	unsigned long arg0 = 0;
	unsigned long arg1 = arg[1]; 	// save it here
	unsigned short u16NrmIntrSignalEn = 0;
	unsigned short u16ErrIntrSignalEn = 0;

	if (type == SUSPEND || type == RESUME)
	{
		db ("send_app_cmd(ACMD%u): Suspend/Resume are not supported\n", idx);
		return -1;
	}

	if (SSD_REGRL(REG_u32PrsntState) & PSR_INHIBIT_CMD)	{
		db ("send_app_cmd(ACMD%u): Command Inhibit CMD is active\n", idx);
		return -1;
	}

	if (!g_irq) {
		u16NrmIntrSignalEn = SSD_REGRW(REG_u16NrmIntrSignalEn);		u16ErrIntrSignalEn = SSD_REGRW(REG_u16ErrIntrSignalEn);
		SSD_REGWW(REG_u16NrmIntrSignalEn, 0);		// turn off any irqs		SSD_REGWW(REG_u16ErrIntrSignalEn, 0);		// turn off any irqs	}

	SSD_REGWW(REG_u16NrmIntrStatus , SSD_REGRW(REG_u16NrmIntrStatus));	// clear previous status	SSD_REGWW(REG_u16NrmIntrStatusEn, SSD_REGRW(REG_u16NrmIntrStatusEn) | INTR_CMD_COMPLETE);	
	SSD_REGWW(REG_u16ErrIntrStatus,SSD_REGRW(REG_u16ErrIntrStatus)|SSD_REGRW(REG_u16ErrIntrStatus));	// clear previous status	SSD_REGWW(REG_u16ErrIntrStatusEn,SSD_REGRW(REG_u16ErrIntrStatusEn) |			( EINTR_CMD_TOUT | EINTR_CMD_END | EINTR_VS_RSP_DIR |			(crc_check ? EINTR_CMD_CRC : 0) |
			(idx_check ? EINTR_CMD_IDX : 0)));
	SSD_REGWL(REG_u32Arg , SWAP32(arg[0]));	cmd = CMD_IDX (0x37) | CMD_TYPE (NORMAL) | CMD_RSP (R48);
	cmd |= crc_check ? CMDR_CRC_CHECK_EN : 0;
	cmd |= idx_check ? CMDR_IDX_CHECK_EN : 0;


	db ("send_app_cmd (ACMD%u): Present State Register (0x%08lx)\n", idx, SWAP32(SSD_REGRL(REG_u32PrsntState)));	SSD_REGWW(REG_u16Cmd , cmd);
	for (i = 0; i < MAX_WAIT; i++)
		if (SSD_REGRL(REG_u32PrsntState) & PSR_INHIBIT_CMD)		{			break;
		}#if 0
	if (i == MAX_WAIT)
	{
		db ("send_app_cmd (ACMD%u): Command Inhibit (CMD) not set, test failed\n", idx);
		return -1;
	}
#endif
	// wait for command complete or error
	for (i = 0; i < MAX_WAIT; i++)
	{
		if (SSD_REGRW(REG_u16NrmIntrStatus) & (INTR_CMD_COMPLETE | INTR_ERR))				break;
//		delay_us (1);
	}

	arg0 = SWAP32 (SSD_REGRL(REG_a32Rsp));	// arg[0] - contains response to CMD55	arg[0] = arg0;
	arg[1] = SWAP32 (SSD_REGRL(REG_a32Rsp+4));	arg[2] = SWAP32 (SSD_REGRL(REG_a32Rsp+8));	arg[3] = SWAP32 (SSD_REGRL(REG_a32Rsp+12));#if 1
	db ("send_app_cmd (CMD55): NISR (0x%04x), NISREN (0x%04x)\n", 
			SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16NrmIntrStatusEn)) );	db ("send_app_cmd (CMD55): EISR (0x%04x), EISREN (0x%04x)\n", 
			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatusEn)) );	db ("send_app_cmd (CMD55): (After Command Complete) Present State Register (0x%08lx)\n", 
			SWAP32(SSD_REGRL(REG_u32PrsntState)));	db ("send_app_cmd (CMD55): RSP[127..0] = 0x%08lx %08lx %08lx %08lx\n", 
			arg[3], arg[2], arg[1], arg[0]);
#endif
	if (i == MAX_WAIT)
	{
		db ("send_app_cmd (CMD55): Timeout waiting for Command Complete\n");
		error = 1;
		goto l_err;
	}

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)	{
		db ("send_app_cmd (CMD55): Command resulted in Error, ErrIntrStatus (0x%04x)\n", 
			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));		SSD_REGWW(REG_u16ErrIntrStatus , SSD_REGRW(REG_u16ErrIntrStatus));		if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)		{
			db ("send_app_cmd (CMD55): NISR.INTR_ERR(b15) could not be cleared. "
				"NISR (0x%04x), EISR (0x%04x)\n",
				SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));		}

		SSD_REGWW(REG_u16NrmIntrStatus , INTR_CMD_COMPLETE);		if (SSD_REGRW(REG_u16NrmIntrStatus))		{
			db ("send_app_cmd (CMD55): NISR (0x%04x) -> bits are still set in NISR\n",
				SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)));			SSD_REGWW(REG_u16NrmIntrStatus , SSD_REGRW(REG_u16NrmIntrStatus));		}

		sdhc_reset (SW_RESET_CMD);		error = 1;
		goto l_err;
	}

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_CMD_COMPLETE)	{
		SSD_REGWW(REG_u16NrmIntrStatus , INTR_CMD_COMPLETE);#if 0
		if (SSD_REGWW(REG_u16NrmIntrStatus & INTR_CMD_COMPLETE)		{
			db ("send_app_cmd (ACMD%u): NISR.INTR_CMD_COMPLETE(b0) could not be cleared. "
				"NISR (0x%04x), EISR (0x%04x)\n", 
				idx, SWAP16(SSD_REGWW(REG_u16NrmIntrStatus), SWAP16(SSD_REGWW(REG_u16ErrIntrStatus));			error = 1;
		}
#endif

	}

	SSD_REGWL(REG_u32Arg , SWAP32(arg1));	cmd = CMD_IDX (idx) | CMD_TYPE (NORMAL) | CMD_RSP (R48);
	cmd |= crc_check ? CMDR_CRC_CHECK_EN : 0;
	cmd |= idx_check ? CMDR_IDX_CHECK_EN : 0;

	SSD_REGWW(REG_u16Cmd , cmd);
	for (i = 0; i < MAX_WAIT; i++)
		if (SSD_REGRL(REG_u32PrsntState) & PSR_INHIBIT_CMD)			break;

	if (i == MAX_WAIT)
	{
		db ("App send_app_cmd (ACMD%u): Command Inhibit (CMD) not set, test failed\n", idx);
		error = 1;
		goto l_err;
	}
	// wait for command complete or error
	for (i = 0; i < MAX_WAIT; i++)
	{
		if (SSD_REGRW(REG_u16NrmIntrStatus) & (INTR_CMD_COMPLETE | INTR_ERR))				break;
//		delay_us (1);
	}

	if (i == MAX_WAIT)
	{
		db ("send_app_cmd (ACMD%u): Timeout waiting for Command Complete\n", idx);
		error = 1;
		goto l_err;
	}

	arg1 = SWAP32 (SSD_REGRL(REG_a32Rsp+0));	// arg[0] - contains response to ACMD	arg[0] = arg1;
	arg[1] = SWAP32 (SSD_REGRL(REG_a32Rsp+4) );	arg[2] = SWAP32 (SSD_REGRL(REG_a32Rsp+8) );	arg[3] = SWAP32 (SSD_REGRL(REG_a32Rsp+12) );
#if 0
	db ("send_app_cmd (ACMD%u): NISR (0x%04x), NISREN (0x%04x)\n", 
			idx, SWAP16(SSD_REGWW(REG_u16NrmIntrStatus), SWAP16(SSD_REGWW(REG_u16NrmIntrStatusEn));	db ("send_app_cmd (ACMD%u): EISR (0x%04x), EISREN (0x%04x)\n", 
			idx, SWAP16(SSD_REGWW(REG_u16ErrIntrStatus), SWAP16(SSD_REGWW(REG_u16ErrIntrStatusEn));	db ("send_app_cmd (ACMD%u): (After Command Complete) Present State Register (0x%08lx)\n", 
			idx, SWAP32(SSD_REGWL(REG_u32PrsntState));	db ("send_app_cmd (ACMD%u): RSP[127..0] = 0x%08lx %08lx %08lx %08lx\n", 
			idx, arg[3], arg[2], arg[1], arg[0]);
#endif

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)	{
		db ("send_app_cmd (ACMD%u): Command resulted in Error, ErrIntrStatus (0x%04x)\n", 
			idx, SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));

⌨️ 快捷键说明

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