📄 sdreg.c
字号:
if (idx == 41 && error) { //db ("send_app_cmd (ACMD%u): Result = %s\n\r", idx, (error ? "No response": "Passed")); } else { //db ("send_app_cmd (ACMD%u): Result = %s\n\r", 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\r", // 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\r"); 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\r"); return -1; } } else { db ("Card Detected at socket but status not reflected in PSR_CARD_INSERTED!\n\r"); return -1; } db ("Card detected and insertion is stable\n\r"); 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\r"); 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\r"); } 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\r"); return -1; } db ("Clock Control: Internal Clock disabled\n\r"); } 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\r"); } 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\r",SSD_REGRB(REG_u8ClkCntl)); return -1; } db ("Clock Control: Internal clock oscillation enabled and stable\n\r"); } 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\r"); return -1; } SSD_REGWB(REG_u8ClkCntl , (UINT8)((~CCR_SDCLK_EN)&0xff)); 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\r",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\r"); return -1; }#if 0 if (sdhc_card_select (sdhc, rca, 0) < 0) return -1;#endif //db ("sdhc_read_scr: Passed\n\r"); 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_SD (CMD_APP_CMD, NORMAL, R48, 0, 1, 1, rsp) < 0) { //db ("read_scr: CMD55 failed\n\r"); return -1; } if (rsp[0] & R1_STAT_ERR || (!(rsp[0] & R1_STAT_APP_CMD))) { //db ("read_scr: (CMD55) Card Status reports error\n\r"); 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\r", sizeof(SCR_T)); rsp[0] = 0xffffffffUL; if (send_cmd_SD (ACMD_SEND_SCR, NORMAL, R48, 1, 1, 1, rsp) < 0) { //db ("read_scr: ACMD51 failed\n\r"); return -1; } if (rsp[0] & R1_STAT_ERR) { //db ("read_scr: (ACMD51) Card Status reports error\n\r"); 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\r"); //db ("read_scr: NISR=0x%04x, EISR=0x%04x, PSR=0x%08lx\n\r", // 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\r", // 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\r"); 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\r", // 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\r"); 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\r"); } //db ("scr data: %02x %02x %02x %02x %02x %02x %02x %02x\n\r", // 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\r"); 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\r");#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_SD (CMD_APP_CMD, NORMAL, R48, 0, 1, 1, rsp) < 0) { //db ("get_wr_blk_count: CMD55 failed\n\r"); 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\r"); 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_SD (ACMD_SEND_NUM_WR_BLK, NORMAL, R48, 1, 1, 1, rsp) < 0) { //db ("get_wr_blk_count: ACMD22 failed\n\r"); return -1; } if (rsp[0] & R1_STAT_ERR) { //db ("get_wr_blk_count: (ACMD22) Card Status reports error\n\r"); 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\r"); //db ("get_wr_blk_count: NISR=0x%04x, EISR=0x%04x, PSR=0x%08lx\n\r", // 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\r", 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\r"); 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\r", // SWAP32 (SSD_REGRL(REG_u32PrsntState))); } } else { //db ("get_wr_blk_count: INTR_BUF_RD_RDY is not set.\n\r"); 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\r", 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]; rsp[0] = start_addr; if (send_cmd_SD ((cardtype & CARDTYPE_SDMEM) ? CMD_ERASE_SADDR : CMD_ERASE_GRP_SADDR, NORMAL, R48, 0, 1, 1, rsp) < 0) { //db ("CMD_ERASE_SADDR failed\n\r"); 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\r"); decode_r1 (rsp[0]); return -1; } rsp[0] = start_addr + nblk*g_length - 1; if (send_cmd_SD ((cardtype & CARDTYPE_SDMEM) ? CMD_ERASE_EADDR : CMD_ERASE_GRP_EADDR, NORMAL, R48, 0, 1, 1, rsp) < 0) { //db ("CMD_ERASE_EADDR failed\n\r"); 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\r"); decode_r1 (rsp[0]); return -1; } rsp[0] = 0xffffffffUL; if (send_cmd_SD (CMD_ERASE, NORMAL, R48b, 0, 1, 1, rsp) < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -