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

📄 sdregb.c

📁 ssd192Xv1 液晶驱动程序 驱动程序 彩屏液晶
💻 C
📖 第 1 页 / 共 5 页
字号:
		SSD_REGWW(REG_u16ErrIntrStatus,  SSD_REGRW(REG_u16ErrIntrStatus));		if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)		{
			db ("send_app_cmd (ACMD%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)));		}

		if (SSD_REGRW(REG_u16NrmIntrStatus))		{
			db ("send_app_cmd (ACMD%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));		}

		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);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));
	arg[0] = arg0;
	arg[1] = arg1;

	if (idx == 41 && error)
		db ("send_app_cmd (ACMD%u): Result = %s\n", idx, (error ? "No response": "Passed"));
	else
		db ("send_app_cmd (ACMD%u): Result = %s\n", idx, (error ? "Failed": "Passed"));

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

	return (error ? -1 : 0);
}

int bus_pwr (int pwr){
	SSD_REGWB(REG_u8PwrCntl ,SSD_REGRB(REG_u8PwrCntl)& ~PCR_SDBUS_PWRON);	if (pwr)	// turn on power
	{
		if (SSD_REGRL(REG_u32Capabilities) & CAP_SDBUS_V1_8)			SSD_REGWB(REG_u8PwrCntl , PCR_SDBUS_V1_8);		else if (SSD_REGRL(REG_u32Capabilities) & CAP_SDBUS_V3_0)			SSD_REGWB(REG_u8PwrCntl , PCR_SDBUS_V3_0);		else if (SSD_REGRL(REG_u32Capabilities) & CAP_SDBUS_V3_3)			SSD_REGWB(REG_u8PwrCntl , PCR_SDBUS_V3_3);		else
		{
			db ("Capabilities Register has no Bus Pwer information, Capabilities: 0x%lx\n", 
					SWAP32(SSD_REGRL(REG_u32Capabilities)));			return -1;
		}
		SSD_REGWB(REG_u8PwrCntl,SSD_REGRB(REG_u8PwrCntl) | PCR_SDBUS_PWRON);	}

	return 0;
}

int card_detect (){
	int i;

	// check if a card is inserted, else report card missing and return
	
	if (!(SSD_REGRL(REG_u32PrsntState) & PSR_CARD_DET_PIN))	{
		db ("Please insert card before continuing\n");
		return -1;
	}

	if (SSD_REGRL(REG_u32PrsntState) & PSR_CARD_INSERTED)	{
		for (i = 0; i < MAX_WAIT; i++)
		{
			if (SSD_REGRL(REG_u32PrsntState) & PSR_CARD_STABLE)				break;
		}
		if (i == MAX_WAIT)
		{
			db ("Card insertion has failed to stabilise\n");
			return -1;
		}
	}
	else
	{
		db ("Card Detected at socket but status not reflected in PSR_CARD_INSERTED!\n");
		return -1;
	}

	db ("Card detected and insertion is stable\n");
	return 0;
}

int clock_cntl (unsigned short clocks, unsigned short div, int enable){
	int i;

	if (!enable)
	{
		// disable clocks
		if ((SSD_REGRB(REG_u8ClkCntl) & CCR_SDCLK_EN) && !(clocks & CCR_SDCLK_EN))		{
			db ("Clock Control: Auto-disabling SD Clock before Internal Clock\n");
			clocks |= CCR_SDCLK_EN;
		}

		if (clocks & CCR_SDCLK_EN)
		{
			SSD_REGWB(REG_u8ClkCntl,SSD_REGRB(REG_u8ClkCntl) & ~CCR_SDCLK_EN);			db ("Clock Control: SD Clk disabled\n");
		}

		if (clocks & CCR_ICLK_EN)
		{
			SSD_REGWB(REG_u8ClkCntl, SSD_REGRB(REG_u8ClkCntl) & ~CCR_ICLK_EN);			if (SSD_REGRB(REG_u8ClkCntl) & CCR_ICLK_STABLE)			{
				db ("Clock Control: Internal Clock Stable bit is still "
					"set after internal clock has been disabled\n");
				return -1;
			}
			db ("Clock Control: Internal Clock disabled\n");
		}

		return 0;
	}

	// enable clock

	if (clocks & CCR_ICLK_EN)
	{
		if (SSD_REGRB(REG_u8ClkCntl) & CCR_SDCLK_EN)		{
			SSD_REGWB(REG_u8ClkCntl ,SSD_REGRB(REG_u8ClkCntl)& ~CCR_SDCLK_EN);			db ("Clock Control: SDCLK disabled\n");
		}

		SSD_REGWB(REG_u8ClkCntl, SSD_REGRB(REG_u8ClkCntl) | CCR_ICLK_EN);		for (i = 0; i < MAX_WAIT; i++)
		{
			if (SSD_REGRB(REG_u8ClkCntl) & CCR_ICLK_STABLE)				break;
		}
		if (i == MAX_WAIT)
		{
			db ("Clock Control: Internal clock oscillation failed to reach stability (CCR: 0x%04x)\n",SSD_REGRB(REG_u8ClkCntl));			return -1;
		}
		db ("Clock Control: Internal clock oscillation enabled and stable\n");
	}

	if (clocks & CCR_SDCLK_EN)
	{
		if ((SSD_REGRB(REG_u8ClkCntl) & (CCR_ICLK_EN|CCR_ICLK_STABLE)) != 				(CCR_ICLK_EN | CCR_ICLK_STABLE))
		{
			db ("Clock Control: Attempt to enable SD Clock before internal clock is enabled or and stable\n");
			return -1;
		}

		SSD_REGWB(REG_u8ClkCntl , ~CCR_SDCLK_EN);		SSD_REGWB(REG_u8ClkDiv , div);		SSD_REGWB(REG_u8ClkCntl ,SSD_REGRB(REG_u8ClkCntl)| CCR_SDCLK_EN);
		db ("Clock Control: SD Clock enabled (0x%2x), SD Clock Frequency (0x%2x)\n",
			SSD_REGRB(REG_u8ClkCntl), SSD_REGRB(REG_u8ClkDiv));	}

	return 0;
}

int sdhc_read_scr (unsigned short rca, SCR_T *scr){
	if (sdhc_card_select (rca, 1) < 0)		return -1;

	if (read_scr (rca, scr) < 0)	{
		db ("sdhc_read_scr: Failed\n");
		return -1;
	}

#if 0
	if (sdhc_card_select (sdhc, rca, 0) < 0)
		return -1;
#endif

	db ("sdhc_read_scr: Passed\n");
	return 0;
}

int read_scr (unsigned short rca, SCR_T *scr){
	unsigned long rsp[4];
	unsigned char buf[sizeof(SCR_T)];
	int i;

	rsp[0] = ((unsigned long)rca << 16) | 0xffffUL;
	if (send_cmd (CMD_APP_CMD, NORMAL, R48, 0, 1, 1, rsp) < 0)	{
		db ("read_scr: CMD55 failed\n");
		return -1;
	}

	if (rsp[0] & R1_STAT_ERR || (!(rsp[0] & R1_STAT_APP_CMD)))
	{
		db ("read_scr: (CMD55) Card Status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}

	// enable all status
	
	SSD_REGWW(REG_u16NrmIntrStatusEn, SSD_REGRW(REG_u16NrmIntrStatusEn)| 0xffff);	SSD_REGWW(REG_u16ErrIntrStatusEn, SSD_REGRW(REG_u16ErrIntrStatusEn)| 0xffff);
	// reading a 64-bit block
	SSD_REGWW(REG_u16BlkCount , 0);	SSD_REGWW(REG_u16BlkSize , 0);	// required to reset the fifo
	SSD_REGWW(REG_u16TrnsfrMode , TMR_RD_EN);	SSD_REGWW(REG_u16TrnsfrMode , 0);	SSD_REGWW(REG_u16TrnsfrMode , TMR_RD_EN);	SSD_REGWW(REG_u16BlkSize , SWAP16 (sizeof (SCR_T)));	db ("read_scr: sizeof SCR=%d\n", sizeof(SCR_T));

	rsp[0] = 0xffffffffUL;
	if (send_cmd (ACMD_SEND_SCR, NORMAL, R48, 1, 1, 1, rsp) < 0)	{
		db ("read_scr: ACMD51 failed\n");
		return -1;
	}

	if (rsp[0] & R1_STAT_ERR)
	{
		db ("read_scr: (ACMD51) Card Status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}

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

#if 0
	if (SSD_REGWW(REG_u16NrmIntrStatus & (INTR_ERR | INTR_DAT_COMPLETE | INTR_BUF_RD_RDY))			break;
#endif

	if (i == MAX_WAIT)
	{
		db ("read_scr: sw timeout waiting for transfer complete\n");
		db ("read_scr: NISR=0x%04x, EISR=0x%04x, PSR=0x%08lx\n",
			SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)),			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)),			SWAP32(SSD_REGRL(REG_u32PrsntState)));		return -1;
	}

	db ("read_scr: NISR=0x%04x, EISR=0x%04x, PSR=0x%08lx\n",
			SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)),			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)),			SWAP32(SSD_REGRL(REG_u32PrsntState)));
	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)	{
		db ("read_scr: Failed\n");
		SSD_REGWW(REG_u16ErrIntrStatus , SSD_REGRW(REG_u16ErrIntrStatus));		SSD_REGWW(REG_u16NrmIntrStatus , SSD_REGRW(REG_u16NrmIntrStatus));		return -1;
	}

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_BUF_RD_RDY)	{
		for (i = 0; i < sizeof (SCR_T); i++)
			buf[i] = SSD_REGRB(REG_u8DataPort);		if (SSD_REGRL(REG_u32PrsntState) & PSR_BUF_RDEN)		{
			db ("read_scr: PSR_BUF_RDEN is still set (PSR=0x%08lx)\n", 
				SWAP32 (SSD_REGRL(REG_u32PrsntState)));		}
		SSD_REGWW(REG_u16NrmIntrStatus , INTR_BUF_RD_RDY);	}
	else
	{
		db ("read_scr: INTR_BUF_RD_RDY is not set.\n");
		return -1;
	}

	for (i = 0; i < MAX_WAIT; i++) {
		if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_DAT_COMPLETE) {			SSD_REGWW(REG_u16NrmIntrStatus , INTR_DAT_COMPLETE);			break;
		}
	}

	if (i == MAX_WAIT) {
		db ("read_scr: SW timeout waiting for INTR_DAT_COMPLETE to set.\n");
	}

	db ("scr data: %02x %02x %02x %02x %02x %02x %02x %02x\n",
		buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);

	*scr = *((SCR_T *) (buf));
	return 0;
}

int sdhc_get_wr_blk_count (unsigned short rca, long *nblk){
	if (sdhc_card_select (rca, 1) < 0)		return -1;

	if (get_wr_blk_count (rca, nblk) < 0)	{
		db ("sdhc_get_wr_blk_count: Failed\n");
		return -1;
	}

#if 0
	if (sdhc_card_select (sdhc, rca, 0) < 0)
		return -1;
#endif
#ifndef __KERNEL__
	db ("sdhc_get_wr_blk_count: Passed\n");
#endif
	return 0;
}


int get_wr_blk_count (unsigned short rca, long *nblk){
	unsigned long rsp[4];
	unsigned char buf[4];
	int i;

	rsp[0] = ((unsigned long)rca << 16) | 0xffffUL;
	if (send_cmd (CMD_APP_CMD, NORMAL, R48, 0, 1, 1, rsp) < 0)	{
		db ("get_wr_blk_count: CMD55 failed\n");
		return -1;
	}

	if (rsp[0] & R1_STAT_ERR || (!(rsp[0] & R1_STAT_APP_CMD)))
	{
		db ("get_wr_blk_count: (CMD55) Card Status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}

	// enable all status
	
	SSD_REGWW(REG_u16NrmIntrStatusEn,SSD_REGRW(REG_u16NrmIntrStatusEn) | 0xffff);	SSD_REGWW(REG_u16ErrIntrStatusEn,SSD_REGRW(REG_u16ErrIntrStatusEn) | 0xffff);
	// reading a 64-bit block
	SSD_REGWW(REG_u16BlkCount , 0);	SSD_REGWW(REG_u16BlkSize , 0);	// required to reset the fifo
	SSD_REGWW(REG_u16TrnsfrMode , TMR_RD_EN);	SSD_REGWW(REG_u16TrnsfrMode , 0);	SSD_REGWW(REG_u16TrnsfrMode , TMR_RD_EN);	SSD_REGWW(REG_u16BlkSize , SWAP16 (4));
	rsp[0] = 0xffffffffUL;
	if (send_cmd (ACMD_SEND_NUM_WR_BLK, NORMAL, R48, 1, 1, 1, rsp) < 0)	{
		db ("get_wr_blk_count: ACMD22 failed\n");
		return -1;
	}

	if (rsp[0] & R1_STAT_ERR) {
		db ("get_wr_blk_count: (ACMD22) Card Status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}

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

	if (i == MAX_WAIT) {
		db ("get_wr_blk_count: sw timeout waiting for transfer complete\n");
		db ("get_wr_blk_count: NISR=0x%04x, EISR=0x%04x, PSR=0x%08lx\n",
			SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)),			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)),			SWAP32(SSD_REGRL(REG_u32PrsntState)));		return -1;
	}

#ifndef __KERNEL__
	db ("get_wr_blk_count: NISR=0x%04x, EISR=0x%04x, PSR=0x%08lx\n",
			SWAP16(SSD_REGRW(REG_u16NrmIntrStatus)),			SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)),			SWAP32(SSD_REGRL(REG_u32PrsntState)) );#endif
	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_ERR)	{
		db ("get_wr_blk_count: Failed\n");
		SSD_REGWW(REG_u16ErrIntrStatus , SSD_REGRW(REG_u16ErrIntrStatus));		SSD_REGWW(REG_u16NrmIntrStatus , SSD_REGRW(REG_u16NrmIntrStatus));		return -1;
	}

	if (SSD_REGRW(REG_u16NrmIntrStatus) & INTR_BUF_RD_RDY)	{
		SSD_REGWW(REG_u16NrmIntrStatus , INTR_BUF_RD_RDY);		for (i = 0; i < sizeof (SCR_T); i++)
			buf[i] = SSD_REGRB(REG_u8DataPort);		if (SSD_REGRL(REG_u32PrsntState) & PSR_BUF_RDEN)		{
			db ("get_wr_blk_count: PSR_BUF_RDEN is still set (PSR=0x%08lx)\n", 
				SWAP32 (SSD_REGRL(REG_u32PrsntState)));		}
	}
	else
	{
		db ("get_wr_blk_count: INTR_BUF_RD_RDY is not set.\n");
		return -1;
	}

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

	if (i == MAX_WAIT) {
		db ("get_wr_blk_count: INTR_DAT_COMPLETE is not set in NISR(0x%04x)\n", SWAP16 (SSD_REGRW(REG_u16NrmIntrStatus)));		*nblk = 0;
	} else 
		*nblk = ((unsigned long) buf[0] << 24) | ((unsigned long) buf[1] << 16) | 
			((unsigned long) buf[2] << 8) | (unsigned long) buf[3];

	SSD_REGWW(REG_u16NrmIntrStatusEn , 0);	SSD_REGWW(REG_u16ErrIntrStatusEn , 0);
	return 0;
}

int sdhc_erase (unsigned long cardtype, unsigned short rca, unsigned long start_addr, int nblk){
	unsigned long rsp[4];

⌨️ 快捷键说明

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