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

📄 sdregb.c

📁 ssd192Xv1 液晶驱动程序 驱动程序 彩屏液晶
💻 C
📖 第 1 页 / 共 5 页
字号:
	rsp[0] = start_addr;
	if (send_cmd ((cardtype & CARDTYPE_SDMEM) ? CMD_ERASE_SADDR : CMD_ERASE_GRP_SADDR, 		NORMAL, R48, 0, 1, 1, rsp) < 0)
	{
		db ("CMD_ERASE_SADDR failed\n");
		return -1;
	}

	if (rsp[0] & (R1_STAT_ERR | R1_STAT_ERASE_SEQ_ERR | R1_STAT_ERASE_PARAM_ERR | R1_STAT_ERASE_RST))
	{
		db ("sdhc_erase (CMD_ERASE_SADDR phase): card status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}

	rsp[0] = start_addr + nblk*g_length - 1;
	if (send_cmd ((cardtype & CARDTYPE_SDMEM) ? CMD_ERASE_EADDR : CMD_ERASE_GRP_EADDR, 		NORMAL, R48, 0, 1, 1, rsp) < 0)
	{
		db ("CMD_ERASE_EADDR failed\n");
		return -1;
	}

	if (rsp[0] & (R1_STAT_ERR | R1_STAT_ERASE_SEQ_ERR | R1_STAT_ERASE_PARAM_ERR | R1_STAT_ERASE_RST))
	{
		db ("sdhc_erase (CMD_ERASE_EADDR phase): card status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}

	rsp[0] = 0xffffffffUL;
	if (send_cmd (CMD_ERASE, NORMAL, R48b, 0, 1, 1, rsp) < 0)	{
		db ("CMD_ERASE failed\n");
		return -1;
	}

	if (rsp[0] & (R1_STAT_ERR | R1_STAT_ERASE_SEQ_ERR | R1_STAT_ERASE_PARAM_ERR | R1_STAT_ERASE_RST))
	{
		db ("sdhc_erase (CMD_ERASE phase): card status reports error\n");
		decode_r1 (rsp[0]);
		return -1;
	}
	db ("sdhc_erase: done\n");

	return 0;
}

char *tolowercase (char *s)
{
	char *p = s;
	while (*p)
	{
		if (*p >= 'A' && *p <= 'Z')
			*p += ('a' - 'A');
		p++;
	}

	return s;
}

int sdhc_io_init (int *io_func, int *io_mp, unsigned long *ocr){
#define	R4_IO_RDY	BIT(31)
#define R4_IO_NUMFUNC	(BIT(30)|BIT(29)|BIT(28))
#define R4_IO_MEM_PRSNT	BIT(27)
#define R4_IO_OCR_MASK	0x00FFFFFFUL

#define GET_R4_IO_NUMFUNC(a)	((((a) & R4_IO_NUMFUNC) >> 28) & 0x7UL)

	int	i;
	int	error = 0;
	unsigned long rsp[4];
	
	// send a CMD5 to detect if an SDIO only or SD/SDIO Combo card is present
	rsp[0] = 0;
	if (send_cmd (CMD_IO_SEND_OCR, NORMAL, R48, 0, 0, 0, rsp) < 0) {		db ("sdhc_io_init: failed\n");
		error = 1;
		goto l_err;
	}
	
	db ("sdhc_io_init: CMD_IO_SEND_OCR(Init): R4 Response = 0x%08lx\n", rsp[0]);
	*io_func = GET_R4_IO_NUMFUNC(rsp[0]);
	*io_mp = (rsp[0] & R4_IO_MEM_PRSNT) ? 1 : 0;
	if (*io_func > 0) {
		// check if card supports 3.0V, 3.3V and/or 1.8V operation.
		*ocr = rsp[0] & R4_IO_OCR_MASK;
		if (*ocr & SDHC_OCR_3VRNG)
			*ocr = SDHC_OCR_3V;
		else if (*ocr & SDHC_OCR_33VRNG)
			*ocr = SDHC_OCR_33V;
		else {
			db ("IO Card voltage requirements cannot be supported.\n");
			error = 1;
			goto l_err;
		}

		for (i = 0; i < MAX_PWR_UP; i++) {
			rsp[0] = *ocr & 0x00FFFFFFUL;
			if (send_cmd (CMD_IO_SEND_OCR, NORMAL, R48, 0, 0, 0, rsp) == 0) {				if (rsp[0] & R4_IO_RDY) {
					db ("sdhc_io_init: CMD_IO_SEND_OCR(WV): R4 Response = 0x%08lx\n", rsp[0]);
					db ("IO Card has completed initialisation\n");
					break;
				} else
					sleep (1);
			} else { 
				db ("CMD_IO_SEND_OCR Response failed\n");
				error = 1;
				break;
			}
		}

		if (i == MAX_PWR_UP) {
			db ("SW Timeout waiting for IO Card to Power Up\n");
			db ("IO Function will not be initialised further\n");
			error = 1;
		}
	} 
l_err:
	if (error)
		sdhc_reset (SW_RESET_CMD);
	return error ? -1 : 0;
}

int sdhc_card_init (unsigned short *rca, unsigned long *ocr, CID_T *cid, CSD_T *csd){
	int	error = 0;
	unsigned long rsp[4];
	unsigned long a_cid[4];
	unsigned long a_csd[4];

	// 1. Power up the card
	// 2. Wait for it to stabilise
	// 3. Send CMD0 without response
	// 4. Send CMD with response
	// 5. Send CMD with busy

	if (card_detect () < 0)		return -1;
	if (bus_pwr (1) < 0)		return -1;
	if (clock_cntl ( CCR_ICLK_EN | CCR_SDCLK_EN, SDCLK_DIV_INIT, 1) < 0)		return -1;

	if (sdhc_io_init (&g_io_num_fn, &g_io_mp, &g_ocr) == 0) {		g_cardtype = CARDTYPE_SDIO;
		db ("SDIO Card detected: IO Functions=%d, Memory Present=%s\n",
			g_io_num_fn, g_io_mp ? "True":"False");
	}

	if ((g_cardtype & CARDTYPE_SDIO) && !g_io_mp)
		goto l_done;
	rsp[0] = 0xFFFFFFFF;
	if (send_cmd ( 0, NORMAL, R0, 0, 0, 0, rsp) < 0) {		error = 1;
		goto l_err;
	}
#if (CARD_TYPE == SD_PANASONIC)
	// Panasonic accepts this as per spec
	rsp[0] = 0x0000FFFF;	// b31-b16=RCA(0), b15-b0=stuff bits
#elif (CARD_TYPE == SD_TWINMOS)
	// TwinMOS requires 0?
	rsp[0] = 0x00000000;	// b31-b16=RCA(0), b15-b0=stuff bits
#endif
	rsp[1] = 0x00000000;

	if (send_app_cmd (ACMD_SEND_OCR, NORMAL, R48, 0, 0, rsp) < 0) {		db ("No response to ACMD41! RSP[0]=0x%08lx, RSP[1]=0x%08lx\n", rsp[0], rsp[1]);
		decode_r1 (rsp[0]);
		decode_r1 (rsp[1]);

		db ("Sending CMD0 to Reset Card\n");
		rsp[0] = 0xFFFFFFFF;
		if (send_cmd (0, NORMAL, R0, 0, 0, 0, rsp) < 0) {			error = 1;
			goto l_err;
		}

		db ("Trying CMD1 ...\n");
		rsp[0] = 0;
		if (send_cmd (CMD_SEND_OCR, NORMAL, R48, 0, 0, 0, rsp) < 0) {			error = 1;
			goto l_err;
		} else {
			g_cardtype = CARDTYPE_MMC;
			g_ocr = rsp[0];
			db ("CMD1 Passed! MMC Card Detected. RSP[0]=0x%08lx\n", rsp[0]);

		}
	} else {
		g_cardtype |= CARDTYPE_SDMEM;
		g_ocr = rsp[1];
		db ("ACMD41 Passed! SD Mem Card Detected. RSP[0]=0x%08lx, RSP[1]=0x%08lx\n", rsp[0], rsp[1]);
	}

	// check if card supports 3.0V, 3.3V and/or 1.8V operation.
	if (g_ocr & SDHC_OCR_3VRNG)
		g_ocr = SDHC_OCR_3V;
	else if (g_ocr & SDHC_OCR_33VRNG)
		g_ocr = SDHC_OCR_33V;
	else 
	{
		db ("Memory Card voltage requirements cannot be supported.\n");
		error = 1;
		goto l_err;
	}

	do {
		sleep (1);
		if (g_cardtype & CARDTYPE_SDMEM) {
#if (CARD_TYPE == SD_PANASONIC)
			rsp[0] = 0x0000FFFF;
#elif (CARD_TYPE == SD_TWINMOS)
			rsp[0] = 0x00000000;
#endif
			rsp[1] = g_ocr;
		
			if (send_app_cmd (ACMD_SEND_OCR, NORMAL, R48, 0, 0, rsp) < 0)			{
				db ("ACMD(%d)/Response failed\n", ACMD_SEND_OCR);
				error = 1;
				goto l_err;
			}
		} 
		else if (g_cardtype & CARDTYPE_MMC) {
			rsp[0] = g_ocr;
			if (send_cmd (CMD_SEND_OCR, NORMAL, R48, 0, 0, 0, rsp) < 0)			{
				db ("CMD(%d)/Response failed\n", CMD_SEND_OCR);
				error = 1;
				goto l_err;
			}
		}
	} while (!(((g_cardtype & CARDTYPE_SDMEM) ? rsp[1] : rsp[0]) & 0x80000000));

	db ("Card power is now stable\n");

	rsp[0] = 0xFFFFFFFF;
	if (send_cmd (CMD_SEND_ALL_CID, NORMAL, R136, 0, 1, 1, rsp) < 0)	{
		db ("Command (2) with Response Test failed\n");
		error = 1;
		goto l_err;
	}

	a_cid[3] = rsp[0];
	a_cid[2] = rsp[1];
	a_cid[1] = rsp[2];
	a_cid[0] = rsp[3];

	if (g_cardtype & CARDTYPE_SDMEM) {
		rsp[0] = 0xFFFFFFFF;
		if (send_cmd (CMD_SEND_RCA, NORMAL, R48, 0, 1, 1, rsp) < 0)		{
			db ("sdhc_cmd_test: 1st CMD_SEND_RCA failed\n");
			error = 1;
			goto l_err;
		}
		*rca = (unsigned short) (rsp[0] >> 16);
		db ("card rca (1st request) = %d\n", *rca);
		decode_r6 ((unsigned short)(rsp[0] << 16));
	
		rsp[0] = 0xFFFFFFFF;
		if (send_cmd (CMD_SEND_RCA, NORMAL, R48, 0, 1, 1, rsp) < 0)		{
			db ("sdhc_cmd_test: 2nd CMD_SEND_RCA failed\n");
			error = 1;
			goto l_err;
		}
		*rca = (unsigned short) (rsp[0] >> 16);
		db ("card rca (2nd request) = %d\n", *rca);
		decode_r6 ((unsigned short)(rsp[0] << 16));
	} else if (g_cardtype & CARDTYPE_MMC) {
		*rca = MMC_DEF_RCA;
		rsp[0] = (((unsigned long) *rca) << 16) | 0xffffUL;
		db ("MMC card rca (assigned by host) = 0x%04x\n", *rca);
		if (send_cmd (CMD_SEND_RCA, NORMAL, R48, 0, 1, 1, rsp) < 0)		{
			db ("sdhc_cmd_test: CMD_SEND_RCA failed\n");
			error = 1;
			goto l_err;
		}
		decode_r1 (rsp[0]);
		db ("MMC check status\n");
		rsp[0] = (((unsigned long) *rca) << 16) | 0xffffUL;
		if (send_cmd (CMD_SEND_STATUS, NORMAL, R48, 0, 1, 1, rsp) < 0) {			db ("sdhc_cmd_test: CMD_SET_RCA failed\n");
			error = 1;
			goto l_err;
		} else
			decode_r1 (rsp[0]);
	}

	rsp[0] = (*rca << 16) | 0xFFFF;
	if (send_cmd (CMD_SEND_CID, NORMAL, R136, 0, 1, 1, rsp) < 0)	{
		db ("Command (CMD_SEND_CID) with Response Test failed\n");
		error = 1;
		goto l_err;
	}

#if (ENDIAN == BIG_ENDIAN)
	a_cid[3] = rsp[0];
	a_cid[2] = rsp[1];
	a_cid[1] = rsp[2];
	a_cid[0] = rsp[3];
#else
	// little endian, we need to swap the data because we want to fit it into the
	// CSD structure in the correct byte order
	a_cid[3] = SWAPLONG (rsp[0]);
	a_cid[2] = SWAPLONG (rsp[1]);
	a_cid[1] = SWAPLONG (rsp[2]);
	a_cid[0] = SWAPLONG (rsp[3]);
#endif

	rsp[0] = (*rca << 16) | 0xFFFF;
	if (send_cmd ( CMD_SEND_CSD, NORMAL, R136, 0, 1, 1, rsp) < 0)	{
		db ("Command (CMD_SEND_CSD) with Response Test failed\n");
		error = 1;
		goto l_err;
	}

#if (ENDIAN == BIG_ENDIAN)
	a_csd[3] = rsp[0];
	a_csd[2] = rsp[1];
	a_csd[1] = rsp[2];
	a_csd[0] = rsp[3];
#else
	// little endian, we need to swap the data because we want to fit it into the
	// CSD structure in the correct byte order
	a_csd[3] = SWAPLONG(rsp[0]);
	a_csd[2] = SWAPLONG(rsp[1]);
	a_csd[1] = SWAPLONG(rsp[2]);
	a_csd[0] = SWAPLONG(rsp[3]);
#endif
//	decode_csd ((CSD_T *) a_csd, g_cardtype);
//	decode_cid ((CID_T *) a_cid, g_cardtype);

	*csd = *((CSD_T *) a_csd);
	*cid = *((CID_T *) a_cid);
l_err:
	sdhc_reset (SW_RESET_CMD);l_done:
//	printk("get csd");	if (sdhc_get_csd (g_rca, &g_csd) == 0) {//		printk("decode csd\n");		decode_csd (&g_csd, g_cardtype);
	}
	else
	{
		printk("get csd fail\n");
	}
	if (error)
		db ("Card initialisation unsuccessful\n");
	else
		db ("Card initialisation passed\n");
	return (error ? -1 : 0);
}	

int sdhc_get_csd (unsigned short rca, CSD_T *csd){

	unsigned long	rsp[4];
	unsigned long	tmp[4];


	rsp[0] = (rca << 16) | 0xFFFF;
	if (send_cmd (CMD_SEND_CSD, NORMAL, R136, 0, 1, 1, rsp) < 0)		return -1;

#if (ENDIAN == BIG_ENDIAN)
	tmp[3] = rsp[0];
	tmp[2] = rsp[1];
	tmp[1] = rsp[2];
	tmp[0] = rsp[3];
#else
	tmp[3] = SWAPLONG (rsp[0]);
	tmp[2] = SWAPLONG (rsp[1]);
	tmp[1] = SWAPLONG (rsp[2]);
	tmp[0] = SWAPLONG (rsp[3]);
#endif

	*csd = *((CSD_T *) tmp);
	return 0;
}

int sdhc_get_cid (unsigned short rca, CID_T *cid){

	unsigned long	rsp[4];
	unsigned long	tmp[4];

	rsp[0] = (rca << 16) | 0xFFFF;
	if (send_cmd (CMD_SEND_CID, NORMAL, R136, 0, 1, 1, rsp) < 0)		return -1;
#if (ENDIAN == BIG_ENDIAN)
	tmp[3] = rsp[0];
	tmp[2] = rsp[1];
	tmp[1] = rsp[2];
	tmp[0] = rsp[3];
#else
	tmp[3] = SWAPLONG (rsp[0]);
	tmp[2] = SWAPLONG (rsp[1]);
	tmp[1] = SWAPLONG (rsp[2]);
	tmp[0] = SWAPLONG (rsp[3]);
#endif
	*cid = *((CID_T *) tmp);

	return 0;
}

int sdhc_card_select (unsigned short rca, unsigned short select){
	unsigned long	rsp[4];

	if ((select && g_cs) || (!select && !g_cs))
	{
#ifndef __KERNEL__
		db ("sdhc_card_select: card is already %s\n", select ? "selected" : "deselected");
#endif
		return 0;
	}

	if (select) {
		rsp[0] = ((unsigned long) rca << 16) | 0x0000ffffUL;
		if (send_cmd (CMD_SELECT_CARD, NORMAL, R48, 0, 1, 1, rsp) < 0)			return -1;
	} else {
		// no response expected, since card may think that another card is being auto-selected
		rsp[0] = 0x0000ffffUL;
		if (send_cmd (CMD_SELECT_CARD, NORMAL, R0, 0, 0, 0, rsp) < 0)			return -1;
	}

	if (select && rsp[0] & R1_STAT_ERR)
	{
		db ("sdhc_select: Card %s failed\n", select ? "select" : "deselect");
		return -1;
	}

	g_cs ^= 1;
	return 0;
}

int sdhc_get_status (unsigned long *status){
	unsigned long	rsp[4];

	rsp[0] = (((unsigned long) g_rca) << 16) | 0x0000ffffUL;
	if (send_cmd (CMD_SEND_STATUS, NORMAL, R48, 0, 1, 1, rsp) < 0)		return -1;

	*status = rsp[0];

⌨️ 快捷键说明

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