//--------------------------------------------------------------------------------- void sdmmc_send_acmd41(u32 arg, u32 *resp) { //--------------------------------------------------------------------------------- sdmmc_send_command(55, 0x0000, 0x000); *resp = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1)<<16); sdmmc_send_command(41, (u16)arg, (arg>>16)); *resp = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1)<<16); }
int NO_INLINE sdmmc_sdcard_writesectors(uint32_t sector_no, uint32_t numsectors, uint8_t *in) { if(handelSD.isSDHC == 0) sector_no <<= 9; inittarget(&handelSD); sdmmc_write16(REG_SDSTOP,0x100); #ifdef DATA32_SUPPORT sdmmc_write16(REG_SDBLKCOUNT32,numsectors); #endif sdmmc_write16(REG_SDBLKCOUNT,numsectors); handelSD.data = in; handelSD.size = numsectors << 9; sdmmc_send_command(&handelSD,0x52C19,sector_no); return geterror(&handelSD); }
int NO_INLINE sdmmc_nand_readsectors(uint32_t sector_no, uint32_t numsectors, uint8_t *out) { 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 = out; handelNAND.size = numsectors << 9; sdmmc_send_command(&handelNAND,0x33C12,sector_no); inittarget(&handelSD); return geterror(&handelNAND); }
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; }
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; }
//--------------------------------------------------------------------------------- int sdmmc_sdcard_init() { //--------------------------------------------------------------------------------- u16 sdaddr; u32 resp0; u32 resp1; u32 resp2; u32 resp3; u32 resp4; u32 resp5; u32 resp6; u32 resp7; u32 ocr, ccs, hcs, response; sdmmc_cardready = 0; int oldIME = enterCriticalSection(); sdmmc_write16(REG_SDCLKCTL, 0x20); sdmmc_write16(REG_SDOPT, 0x40EA); // XXX: document me! sdmmc_write16(0x02, 0x400); sdmmc_mask16(REG_SDCLKCTL, 0, 0x100); sdmmc_write16(REG_SDCLKCTL, sdmmc_read16(REG_SDCLKCTL)); sdmmc_mask16(REG_SDCLKCTL, 0x100, 0); sdmmc_mask16(REG_SDCLKCTL, 0, 0x200); sdmmc_mask16(REG_SDCLKCTL, 0, 0x100); // CMD0 sdmmc_send_command(0x0000, 0x0000, 0x0000); sdmmc_send_command(0x0408, 0x01aa, 0x0000); sdmmc_gotcmd8reply = 1; if(sdmmc_timeout) sdmmc_gotcmd8reply = 0; if(sdmmc_gotcmd8reply) hcs = (1<<30); else hcs = 0; ocr = 0x00ff8000; while (1) { sdmmc_send_acmd41(ocr | hcs, &response); if (response & 0x80000000) break; } ccs = response & (1<<30); if(ccs && hcs) sdmmc_sdhc = 1; else sdmmc_sdhc = 0; // CMD2 - get CID sdmmc_send_command(2, 0, 0); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); resp2 = sdmmc_read16(REG_SDRESP2); resp3 = sdmmc_read16(REG_SDRESP3); resp4 = sdmmc_read16(REG_SDRESP4); resp5 = sdmmc_read16(REG_SDRESP5); resp6 = sdmmc_read16(REG_SDRESP6); resp7 = sdmmc_read16(REG_SDRESP7); sdmmc_cid[0] = resp0 | (u32)(resp1<<16); sdmmc_cid[1] = resp2 | (u32)(resp3<<16); sdmmc_cid[2] = resp4 | (u32)(resp5<<16); sdmmc_cid[3] = resp6 | (u32)(resp7<<16); // CMD3 sdmmc_send_command(3, 0, 0); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); sdaddr = resp1; // CMD9 - get CSD sdmmc_send_command(9, 0, sdaddr); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); resp2 = sdmmc_read16(REG_SDRESP2); resp3 = sdmmc_read16(REG_SDRESP3); resp4 = sdmmc_read16(REG_SDRESP4); resp5 = sdmmc_read16(REG_SDRESP5); resp6 = sdmmc_read16(REG_SDRESP6); resp7 = sdmmc_read16(REG_SDRESP7); sdmmc_write16(REG_SDCLKCTL, 0x100); // CMD7 sdmmc_send_command(7, 0, sdaddr); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); // CMD55 sdmmc_send_command(55, 0, sdaddr); // ACMD6 sdmmc_send_command(6, 2, 0); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); sdmmc_send_command(13, 0, sdaddr); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); sdmmc_send_command(16, 0x200, 0x0); resp0 = sdmmc_read16(REG_SDRESP0); resp1 = sdmmc_read16(REG_SDRESP1); sdmmc_write16(REG_SDCLKCTL, sdmmc_read16(REG_SDCLKCTL)); sdmmc_write16(REG_SDBLKLEN, 0x200); sdmmc_mask16(REG_SDCLKCTL, 0x100, 0); sdmmc_cardready = 1; leaveCriticalSection(oldIME); return 0; }