📄 sdregb.c
字号:
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 + -