Exemplo n.º 1
0
int NO_INLINE sdmmc_nand_writesectors(uint32_t sector_no, uint32_t numsectors, uint8_t *in) //experimental
{
	if(handelNAND.isSDHC == 0) sector_no <<= 9;
	inittarget(&handelNAND);
	sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
	sdmmc_write32(REG_SDBLKCOUNT32,numsectors);
#else
	sdmmc_write16(REG_SDBLKCOUNT,numsectors);
#endif
	handelNAND.data = in;
	handelNAND.size = numsectors << 9;
	sdmmc_send_command(&handelNAND,0x52C19,sector_no);
	inittarget(&handelSD);
	return geterror(&handelNAND);
}
Exemplo n.º 2
0
void tmio_init()
{
	tmio_mask16(REG_DATACTL32, 0x0800, 0x0000);
	tmio_mask16(REG_DATACTL32, 0x1000, 0x0000);
	tmio_mask16(REG_DATACTL32, 0x0000, 0x0402);
	tmio_mask16(REG_DATACTL, 0x2200, 0x0002);
#ifdef DATA32_SUPPORT
	tmio_mask16(REG_DATACTL, 0x0020, 0x0000);
	tmio_write16(REG_SDBLKLEN32, TMIO_BBS);
#else
	tmio_mask16(REG_DATACTL32, 0x0020, 0x0000);
	tmio_mask16(REG_DATACTL, 0x0020, 0x0000);
	tmio_write16(REG_SDBLKLEN32, 0);
#endif
	tmio_write16(REG_SDBLKCOUNT32, 1);
	tmio_mask16(REG_SDRESET, 0x0001, 0x0000);
	tmio_mask16(REG_SDRESET, 0x0000, 0x0001);
	tmio_write32(REG_SDIRMASK, ~TMIO_MASK_ALL);
	tmio_mask16(0xFC, 0x0000, 0x00DB);
	tmio_mask16(0xFE, 0x0000, 0x00DB);
	tmio_mask16(REG_SDPORTSEL, 0x0002, 0x0000);
#ifdef DATA32_SUPPORT
	tmio_write16(REG_SDCLKCTL, 0x0020);
	tmio_write16(REG_SDOPT, 0x40EE);
#else
	tmio_write16(REG_SDCLKCTL, 0x0040);
	tmio_write16(REG_SDOPT, 0x40EB);
#endif
	tmio_mask16(REG_SDPORTSEL, 0x0002, 0x0000);
	tmio_write16(REG_SDBLKLEN, TMIO_BBS);
	tmio_write16(REG_SDSTOP, 0);
	
	inittarget(TMIO_DEV_SDMC);
}
Exemplo n.º 3
0
int NO_INLINE sdmmc_sdcard_readsectors(uint32_t sector_no, uint32_t numsectors, uint8_t *out)
{
	if(handelSD.isSDHC == 0) sector_no <<= 9;
	inittarget(&handelSD);
	sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
	sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
	sdmmc_write16(REG_SDBLKLEN32,0x200);
#endif
	sdmmc_write16(REG_SDBLKCOUNT,numsectors);
	handelSD.data = out;
	handelSD.size = numsectors << 9;
	sdmmc_send_command(&handelSD,0x33C12,sector_no);
	return geterror(&handelSD);
}
Exemplo n.º 4
0
int SD_Init()
{
	inittarget(&handelSD);
	//waitcycles(0x3E8);
	waitcycles(0xF000);
	DEBUGPRINT(topScreen, "0x00000 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	sdmmc_send_command(&handelSD,0,0);
	DEBUGPRINT(topScreen, "0x10408 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	sdmmc_send_command(&handelSD,0x10408,0x1AA);
	//uint32_t temp = (handelSD.ret[0] == 0x1AA) << 0x1E;
	uint32_t temp = (handelSD.error & 0x1) << 0x1E;
	
	DEBUGPRINT(topScreen, "0x10769 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	DEBUGPRINT(topScreen, "sd ret: ", handelSD.ret[0], 10, 20 + 15*8, RGB(40, 40, 40), RGB(208, 208, 208));
	DEBUGPRINT(topScreen, "temp: ", temp, 10, 20 + 16*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	//int count = 0;
	uint32_t temp2 = 0;
	do
	{
		do
		{
			sdmmc_send_command(&handelSD,0x10437,handelSD.initarg << 0x10);
			sdmmc_send_command(&handelSD,0x10769,0x00FF8000 | temp);
			temp2 = 1;
		} while ( !(handelSD.error & 1) );
		
		//DEBUGPRINT(topScreen, "sd error ", handelSD.error, 10, 20 + 17*8, RGB(40, 40, 40), RGB(208, 208, 208));
		//DEBUGPRINT(topScreen, "sd ret: ", handelSD.ret[0], 10, 20 + 18*8, RGB(40, 40, 40), RGB(208, 208, 208));
		//DEBUGPRINT(topScreen, "count: ", count++, 10, 20 + 19*8, RGB(40, 40, 40), RGB(208, 208, 208));
	}
	while((handelSD.ret[0] & 0x80000000) == 0);
	//do
	//{
	//	sdmmc_send_command(&handelSD,0x10437,handelSD.initarg << 0x10);
	//	sdmmc_send_command(&handelSD,0x10769,0x00FF8000 | temp);
	//	
	//	DEBUGPRINT(topScreen, "sd error ", handelSD.error, 10, 20 + 17*8, RGB(40, 40, 40), RGB(208, 208, 208));
	//	DEBUGPRINT(topScreen, "sd ret: ", handelSD.ret[0], 10, 20 + 18*8, RGB(40, 40, 40), RGB(208, 208, 208));
	//	DEBUGPRINT(topScreen, "count: ", count++, 10, 20 + 19*8, RGB(40, 40, 40), RGB(208, 208, 208));
	//}
	//while(!(handelSD.ret[0] & 0x80000000));

	if(!((handelSD.ret[0] >> 30) & 1) || !temp)
		temp2 = 0;
	
	handelSD.isSDHC = temp2;
	//handelSD.isSDHC = (handelSD.ret[0] & 0x40000000);
	
	DEBUGPRINT(topScreen, "0x10602 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x10602,0);
	if((handelSD.error & 0x4)) return -1;
	
	DEBUGPRINT(topScreen, "0x10403 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x10403,0);
	if((handelSD.error & 0x4)) return -1;
	handelSD.initarg = handelSD.ret[0] >> 0x10;
	
	DEBUGPRINT(topScreen, "0x10609 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x10609,handelSD.initarg << 0x10);
	if((handelSD.error & 0x4)) return -1;
	
	handelSD.total_size = calcSDSize((uint8_t*)&handelSD.ret[0],-1);
	handelSD.clk = 1;
	setckl(1);
	
	DEBUGPRINT(topScreen, "0x10507 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x10507,handelSD.initarg << 0x10);
	if((handelSD.error & 0x4)) return -1;

	DEBUGPRINT(topScreen, "0x10437 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x10437,handelSD.initarg << 0x10);
	if((handelSD.error & 0x4)) return -1;
	
	DEBUGPRINT(topScreen, "0x10446 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	handelSD.SDOPT = 1;
	sdmmc_send_command(&handelSD,0x10446,0x2);
	if((handelSD.error & 0x4)) return -1;
	
	DEBUGPRINT(topScreen, "0x1040D ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x1040D,handelSD.initarg << 0x10);
	if((handelSD.error & 0x4)) return -1;
	
	DEBUGPRINT(topScreen, "0x10410 ", handelSD.error, 10, 20 + 14*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelSD,0x10410,0x200);
	if((handelSD.error & 0x4)) return -1;
	handelSD.clk |= 0x200;
	
	return 0;
}
Exemplo n.º 5
0
int Nand_Init()
{
	inittarget(&handelNAND);
	waitcycles(0xF000);
	
	DEBUGPRINT(topScreen, "0x00000 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0,0);
	
	DEBUGPRINT(topScreen, "0x10701 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	do
	{
		do
		{
			sdmmc_send_command(&handelNAND,0x10701,0x100000);
			DEBUGPRINT(topScreen, "error ", handelNAND.error, 10, 20 + 17*8, RGB(40, 40, 40), RGB(208, 208, 208));
			DEBUGPRINT(topScreen, "ret: ", handelNAND.ret[0], 10, 20 + 18*8, RGB(40, 40, 40), RGB(208, 208, 208));
			DEBUGPRINT(topScreen, "test ", 3, 10, 20 + 19*8, RGB(40, 40, 40), RGB(208, 208, 208));
		} while ( !(handelNAND.error & 1) );
	}
	while((handelNAND.ret[0] & 0x80000000) == 0);
	
	DEBUGPRINT(topScreen, "0x10602 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0x10602,0x0);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x10403 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0x10403,handelNAND.initarg << 0x10);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x10609 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0x10609,handelNAND.initarg << 0x10);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x10407 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	handelNAND.total_size = calcSDSize((uint8_t*)&handelNAND.ret[0],0);
	handelNAND.clk = 1;
	setckl(1);
	
	sdmmc_send_command(&handelNAND,0x10407,handelNAND.initarg << 0x10);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x10506 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	handelNAND.SDOPT = 1;
	
	sdmmc_send_command(&handelNAND,0x10506,0x3B70100);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x10506 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0x10506,0x3B90100);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x1040D ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0x1040D,handelNAND.initarg << 0x10);
	if((handelNAND.error & 0x4))return -1;
	
	DEBUGPRINT(topScreen, "0x10410 ", handelNAND.error, 10, 20 + 13*8, RGB(40, 40, 40), RGB(208, 208, 208));
	
	sdmmc_send_command(&handelNAND,0x10410,0x200);
	if((handelNAND.error & 0x4))return -1;
	
	handelNAND.clk |= 0x200; 
	
	inittarget(&handelSD);
	
	return 0;
}
Exemplo n.º 6
0
void InitSD()
{
	//NAND
	handelNAND.isSDHC = 0;
	handelNAND.SDOPT = 0;
	handelNAND.res = 0;
	handelNAND.initarg = 1;
	handelNAND.clk = 0x80;
	handelNAND.devicenumber = 1;
	
	//SD
	handelSD.isSDHC = 0;
	handelSD.SDOPT = 0;
	handelSD.res = 0;
	handelSD.initarg = 0;
	handelSD.clk = 0x80;
	handelSD.devicenumber = 0;
	
	//sdmmc_mask16(0x100,0x800,0);
	//sdmmc_mask16(0x100,0x1000,0);
	//sdmmc_mask16(0x100,0x0,0x402);
	//sdmmc_mask16(0xD8,0x22,0x2);
	//sdmmc_mask16(0x100,0x2,0);
	//sdmmc_mask16(0xD8,0x22,0);
	//sdmmc_write16(0x104,0);
	//sdmmc_write16(0x108,1);
	//sdmmc_mask16(REG_SDRESET,1,0); //not in new Version -- nintendo's code does this
	//sdmmc_mask16(REG_SDRESET,0,1); //not in new Version -- nintendo's code does this
	//sdmmc_mask16(0x20,0,0x31D);
	//sdmmc_mask16(0x22,0,0x837F);
	//sdmmc_mask16(0xFC,0,0xDB);
	//sdmmc_mask16(0xFE,0,0xDB);
	////sdmmc_write16(REG_SDCLKCTL,0x20);
	////sdmmc_write16(REG_SDOPT,0x40EE);
	////sdmmc_mask16(0x02,0x3,0);
	//sdmmc_write16(REG_SDCLKCTL,0x40);
	//sdmmc_write16(REG_SDOPT,0x40EB);
	//sdmmc_mask16(0x02,0x3,0);
	//sdmmc_write16(REG_SDBLKLEN,0x200);
	//sdmmc_write16(REG_SDSTOP,0);
	
	*(volatile uint16_t*)0x10006100 &= 0xF7FFu; //SDDATACTL32
	*(volatile uint16_t*)0x10006100 &= 0xEFFFu; //SDDATACTL32
#ifdef DATA32_SUPPORT
	*(volatile uint16_t*)0x10006100 |= 0x402u; //SDDATACTL32
#else
	*(volatile uint16_t*)0x10006100 |= 0x402u; //SDDATACTL32
#endif
	*(volatile uint16_t*)0x100060D8 = (*(volatile uint16_t*)0x100060D8 & 0xFFDD) | 2;
#ifdef DATA32_SUPPORT
	*(volatile uint16_t*)0x10006100 &= 0xFFFFu; //SDDATACTL32
	*(volatile uint16_t*)0x100060D8 &= 0xFFDFu; //SDDATACTL
	*(volatile uint16_t*)0x10006104 = 512; //SDBLKLEN32
#else
	*(volatile uint16_t*)0x10006100 &= 0xFFFDu; //SDDATACTL32
	*(volatile uint16_t*)0x100060D8 &= 0xFFDDu; //SDDATACTL
	*(volatile uint16_t*)0x10006104 = 0; //SDBLKLEN32
#endif
	*(volatile uint16_t*)0x10006108 = 1; //SDBLKCOUNT32
	*(volatile uint16_t*)0x100060E0 &= 0xFFFEu; //SDRESET
	*(volatile uint16_t*)0x100060E0 |= 1u; //SDRESET
	*(volatile uint16_t*)0x10006020 |= TMIO_MASK_ALL; //SDIR_MASK0
	*(volatile uint16_t*)0x10006022 |= TMIO_MASK_ALL>>16; //SDIR_MASK1
	*(volatile uint16_t*)0x100060FC |= 0xDBu; //SDCTL_RESERVED7
	*(volatile uint16_t*)0x100060FE |= 0xDBu; //SDCTL_RESERVED8
	*(volatile uint16_t*)0x10006002 &= 0xFFFCu; //SDPORTSEL
#ifdef DATA32_SUPPORT
	*(volatile uint16_t*)0x10006024 = 0x20;
	*(volatile uint16_t*)0x10006028 = 0x40EE;
#else
	*(volatile uint16_t*)0x10006024 = 0x40; //Nintendo sets this to 0x20
	*(volatile uint16_t*)0x10006028 = 0x40EB; //Nintendo sets this to 0x40EE
#endif
	*(volatile uint16_t*)0x10006002 &= 0xFFFCu; ////SDPORTSEL
	*(volatile uint16_t*)0x10006026 = 512; //SDBLKLEN
	*(volatile uint16_t*)0x10006008 = 0; //SDSTOP
	
	inittarget(&handelSD);
}
Exemplo n.º 7
0
uint32_t tmio_wrprotected(enum tmio_dev_id target)
{
	inittarget(target);
	return tmio_read32(REG_SDSTATUS) & TMIO_STAT_WRPROTECT;
}
Exemplo n.º 8
0
uint32_t tmio_init_sdmc()
{
	uint32_t resp;
	uint32_t r;

	if (tmio_dev[TMIO_DEV_SDMC].total_size > 0)
		return 0;

	//SD
	tmio_dev[TMIO_DEV_SDMC].isSDHC = 0;
	tmio_dev[TMIO_DEV_SDMC].SDOPT = 0;
	tmio_dev[TMIO_DEV_SDMC].res = 0;
	tmio_dev[TMIO_DEV_SDMC].initarg = 0;
	tmio_dev[TMIO_DEV_SDMC].clk = 0x80;

	inittarget(TMIO_DEV_SDMC);
	waitcycles(0xF000);
	tmio_send_command(MMC_IDLE,0,0);

	r = tmio_send_command(SD_SEND_IF_COND | TMIO_CMD_RESP_R1,0x1AA,1);
	if(r)
		return r;

	uint32_t temp = tmio_wait_respend() ? 0 : 0x1 << 0x1E;

	uint32_t temp2 = 0;
	do
	{
		while(1)
		{
			tmio_send_command(MMC_APP_CMD | TMIO_CMD_RESP_R1,
				tmio_dev[TMIO_DEV_SDMC].initarg << 0x10,0);
			temp2 = 1;
			if(tmio_send_command(SD_APP_OP_COND
				| TMIO_CMD_APP | TMIO_CMD_RESP_R3,
				0x00FF8000 | temp,1))
				continue;
			if(!tmio_wait_respend())
				break;
		}

		resp = tmio_read32(REG_SDRESP0);
	}
	while((resp & 0x80000000) == 0);

	if(!((resp >> 30) & 1) || !temp)
		temp2 = 0;
	
	tmio_dev[TMIO_DEV_SDMC].isSDHC = temp2;
	
	tmio_send_command(MMC_ALL_SEND_CID | TMIO_CMD_RESP_R2,0,0);
	
	r = tmio_send_command(MMC_SET_RELATIVE_ADDR | TMIO_CMD_RESP_R1,0,1);
	if(r)
		return r;

	r = tmio_wait_respend();
	if(r)
		return r;

	tmio_dev[TMIO_DEV_SDMC].initarg = tmio_read32(REG_SDRESP0) >> 0x10;
	tmio_send_command(MMC_SEND_CSD | TMIO_CMD_RESP_R2,
		tmio_dev[TMIO_DEV_SDMC].initarg << 0x10,0);
	r = tmio_wait_respend();
	if(r)
		return r;

	tmio_dev[TMIO_DEV_SDMC].total_size = calcSDSize((uint8_t*)TMIO_BASE + REG_SDRESP0,-1);
	tmio_dev[TMIO_DEV_SDMC].clk = 1;
	setckl(1);
	
	tmio_send_command(MMC_SELECT_CARD | TMIO_CMD_RESP_R1B,
		tmio_dev[TMIO_DEV_SDMC].initarg << 0x10,0);
	r = tmio_send_command(MMC_APP_CMD | TMIO_CMD_RESP_R1,
		tmio_dev[TMIO_DEV_SDMC].initarg << 0x10,1);
	if(r)
		return r;
	
	tmio_dev[TMIO_DEV_SDMC].SDOPT = 1;
	r = tmio_send_command(MMC_SWITCH | TMIO_CMD_APP | TMIO_CMD_RESP_R1,
		0x2,1);
	if(r)
		return r;

	r = tmio_send_command(MMC_SEND_STATUS | TMIO_CMD_RESP_R1,
		tmio_dev[TMIO_DEV_SDMC].initarg << 0x10,1);
	if(r)
		return r;
	
	r = tmio_send_command(MMC_SET_BLOCKLEN | TMIO_CMD_RESP_R1,TMIO_BBS,1);
	if(r)
		return r;

	tmio_dev[TMIO_DEV_SDMC].clk |= 0x200;
	
	return 0;
}
Exemplo n.º 9
0
uint32_t tmio_init_nand()
{
	uint32_t r;

	if (tmio_dev[TMIO_DEV_NAND].total_size > 0)
		return 0;

	//NAND
	tmio_dev[TMIO_DEV_NAND].isSDHC = 0;
	tmio_dev[TMIO_DEV_NAND].SDOPT = 0;
	tmio_dev[TMIO_DEV_NAND].res = 0;
	tmio_dev[TMIO_DEV_NAND].initarg = 1;
	tmio_dev[TMIO_DEV_NAND].clk = 0x80;

	inittarget(TMIO_DEV_NAND);
	waitcycles(0xF000);
	
	tmio_send_command(MMC_IDLE,0,0);
	
	do
	{
		do
			tmio_send_command(MMC_SEND_OP_COND | TMIO_CMD_RESP_R3,
				0x100000,0);
		while (tmio_wait_respend());
	}
	while((tmio_read32(REG_SDRESP0) & 0x80000000) == 0);
	
	tmio_send_command(MMC_ALL_SEND_CID | TMIO_CMD_RESP_R2,0x0,0);
	r = tmio_send_command(MMC_SET_RELATIVE_ADDR | TMIO_CMD_RESP_R1,
		tmio_dev[TMIO_DEV_NAND].initarg << 0x10,1);
	if(r)
		return r;

	r = tmio_send_command(MMC_SEND_CSD | TMIO_CMD_RESP_R2,
		tmio_dev[TMIO_DEV_NAND].initarg << 0x10,1);
	if(r)
		return r;

	r = tmio_wait_respend();
	if(r)
		return r;
	
	tmio_dev[TMIO_DEV_NAND].total_size = calcSDSize((uint8_t*)TMIO_BASE + REG_SDRESP0,0);
	tmio_dev[TMIO_DEV_NAND].clk = 1;
	setckl(1);
	
	tmio_send_command(MMC_SELECT_CARD | TMIO_CMD_RESP_R1,
		tmio_dev[TMIO_DEV_NAND].initarg << 0x10,0);

	tmio_dev[TMIO_DEV_NAND].SDOPT = 1;

	r = tmio_send_command(MMC_SWITCH | TMIO_CMD_RESP_R1B,0x3B70100,1);
	if(r)
		return r;

	r = tmio_send_command(MMC_SWITCH | TMIO_CMD_RESP_R1B,0x3B90100,1);
	if(r)
		return r;

	r = tmio_send_command(MMC_SEND_STATUS | TMIO_CMD_RESP_R1,
		tmio_dev[TMIO_DEV_NAND].initarg << 0x10,1);
	if(r)
		return r;

	r = tmio_send_command(MMC_SET_BLOCKLEN | TMIO_CMD_RESP_R1,TMIO_BBS,1);
	if(r)
		return r;

	tmio_dev[TMIO_DEV_NAND].clk |= 0x200;
	
	inittarget(TMIO_DEV_SDMC);
	
	return 0;
}
Exemplo n.º 10
0
uint32_t tmio_writesectors(enum tmio_dev_id target,
	uint32_t sector_no, uint32_t numsectors, uint8_t *in)
{
	uint32_t error, mask;

	if(tmio_dev[target].isSDHC == 0) sector_no <<= 9;
	inittarget(target);
	tmio_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
	tmio_write16(REG_SDBLKCOUNT32,numsectors);
	tmio_write16(REG_SDBLKLEN32,TMIO_BBS);
#endif
	tmio_write16(REG_SDBLKCOUNT,numsectors);

	mask = TMIO_MASK_GW;
#ifdef DATA32_SUPPORT
	tmio_write16(REG_DATACTL32,TMIO32_ENABLE | TMIO32_IRQ_TXRQ);
#else
	mask |= TMIO_STAT_RXRDY;
#endif
	tmio_write32(REG_SDIRMASK,~mask);

	tmio_send_command(MMC_WRITE_BLOCK_MULTI
		| TMIO_CMD_RESP_R1 | TMIO_CMD_DATA_PRESENT
		| TMIO_CMD_TRANSFER_MULTI,
		sector_no, 0);

#ifdef DATA32_SUPPORT
	uint32_t *dataPtr32 = (uint32_t*)in;
#else
	uint16_t *dataPtr = (uint16_t*)in;
#endif

	while(numsectors > 0)
	{
		tmio_wfi();

		error = tmio_read32(REG_SDSTATUS) & TMIO_MASK_GW;
		if(error)
			return error;

#ifdef DATA32_SUPPORT
		if((tmio_read16(REG_DATACTL32) & TMIO32_STAT_BUSY))
			continue;
#endif

		#ifdef DATA32_SUPPORT
		for(int i = 0; i<TMIO_BBS; i+=4)
		{
			tmio_write32(REG_SDFIFO32,*dataPtr32++);
		}
		#else
		for(int i = 0; i<TMIO_BBS; i+=2)
		{
			tmio_write16(REG_SDFIFO,*dataPtr++);
		}
		#endif
		numsectors--;
	}

	waitDataend = 1;
	return 0;
}
Exemplo n.º 11
0
uint32_t tmio_readsectors(enum tmio_dev_id target,
	uint32_t sector_no, uint32_t numsectors, uint8_t *out)
{
	uint32_t error, mask;

	if(tmio_dev[target].isSDHC == 0) sector_no <<= 9;
	inittarget(target);
	tmio_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
	tmio_write16(REG_SDBLKCOUNT32,numsectors);
	tmio_write16(REG_SDBLKLEN32,TMIO_BBS);
#endif
	tmio_write16(REG_SDBLKCOUNT,numsectors);

	mask = TMIO_MASK_GW;
#ifdef DATA32_SUPPORT
	tmio_write16(REG_DATACTL32,TMIO32_ENABLE | TMIO32_IRQ_RXRDY);
#else
	mask |= TMIO_STAT_RXRDY;
#endif

	tmio_write32(REG_SDIRMASK,~mask);
	tmio_send_command(MMC_READ_BLOCK_MULTI
		| TMIO_CMD_RESP_R1 | TMIO_CMD_DATA_PRESENT
		| TMIO_CMD_TRANSFER_READ | TMIO_CMD_TRANSFER_MULTI,
		sector_no, 0);

	uint16_t *dataPtr = (uint16_t*)out;
	uint32_t *dataPtr32 = (uint32_t*)out;
	int useBuf32 = 0 == (3 & ((uint32_t)dataPtr));

	while(numsectors > 0)
	{
		tmio_wfi();

		error = tmio_read32(REG_SDSTATUS) & TMIO_MASK_GW;
		if(error)
			return error;

#ifdef DATA32_SUPPORT
		if(!(tmio_read16(REG_DATACTL32) & TMIO32_STAT_RXRDY))
			continue;
#endif

		#ifdef DATA32_SUPPORT
		if(useBuf32)
		{
			for(int i = 0; i<TMIO_BBS; i+=4)
			{
				*dataPtr32++ = tmio_read32(REG_SDFIFO32);
			}
		}
		else
		{
		#endif
			for(int i = 0; i<TMIO_BBS; i+=2)
			{
				*dataPtr++ = tmio_read16(REG_SDFIFO);
			}
		#ifdef DATA32_SUPPORT
		}
		#endif
		numsectors--;
	}

	return 0;
}