📄 sdhc.c
字号:
SDHC_SetTransferModeReg(0, 1, 0, 0, 0, sCh); // Read One Block if ( SDHC_IssueCommand( sCh, 61, (u32)((0<<31)|(0x10)), SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE) == FALSE ) { return FALSE; } sCh->m_uRemainBlock = 1; sCh->m_uBufferPtr = (u32*)buffer; SDHC_ReadOneBlock( sCh, 0); SDHC_INT_WAIT_CLEAR( sCh, 1, i ); // SDHC_TRANSFERCOMPLETE_STS_INT_EN sdDbg(( "serial num : %20s\n", buffer+20 )); sdDbg(( "firmware num : %8s\n", buffer+46 )); sdDbg(( "model num : %40s\n", buffer+54 )); sdDbg(( "version :%d\n", buffer+160 )); sdDbg(( "maximum user LBA : %d\n", (u32*)(buffer+200) )); sdDbg(( "device global unique identifier : %x\n", buffer+216 )); sdDbg(( "maximum write per address : %d\n", buffer+414 )); return TRUE;}//////////// File Name : SDHC_CeATAGetStatus// File Description : This function gets status value from CE-ATA Device.// Input : SDHC channel// Output : NONEvoid SDHC_CeATAGetStatus( SDHC* sCh ) { SDHC_IssueCommand( sCh, 39, (sCh->m_uRca<<16)|(0<<15)|(0xF<<8), SDHC_CMD_AC_TYPE, SDHC_RES_R4_TYPE ); sdDbg( ( "ATA Status : %08x\n", Inp32(sCh->m_uBaseAddr+SDHC_RSP0) ));}//////////// File Name : SDHC_CEATAWriteBlocks// File Description : This function writes user-data only for CE-ATA device.// Input : start block, block count, source buffer address, SDHC channel// Output : Success or Failurebool SDHC_CEATAWriteBlocks(u32 uStBlock, u16 uBlocks, u32 uBufAddr, SDHC* sCh) { SDHC_ataTaskFile taskFile; if ( SDHC_SetCeATATaskFile( sCh, SDHC_ATCMD_WRITE_DMA_EXT, uStBlock, uBlocks, &taskFile ) == FALSE ) { return FALSE; } INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn ); INTC_Enable( sCh->m_ucIntChannelNum ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE, ~(SDHC_DMA_SIG_INT_EN|SDHC_BLOCKGAP_EVENT_SIG_INT_EN) ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, SDHC_DMA_SIG_INT_EN| SDHC_CCS_INTERRUPT_STATUS_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN ); sCh->m_uCCSResponse = 0x1; Outp32( sCh->m_uBaseAddr+SDHC_CONTROL2, Inp32(sCh->m_uBaseAddr+SDHC_CONTROL2)|(1<<11) ); SDHC_SetSystemAddressReg(sCh, (u32)uBufAddr);// AHB System Address For Write SDHC_SetBlockSizeReg(sCh, 7, 512); // Maximum DMA Buffer Size, Block Size SDHC_SetBlockCountReg(sCh, uBlocks); // Block Numbers to Read SDHC_SetTransferModeReg(1, 0, 0, 1, 1, sCh); Outp16( sCh->m_uBaseAddr+SDHC_TRANS_MODE, (Inp16(sCh->m_uBaseAddr+SDHC_TRANS_MODE)&~(0x3<<8))|(sCh->m_uCCSResponse<<8)); sCh->m_uRemainBlock = uBlocks; sCh->m_uBufferPtr = (u32*)uBufAddr; // Write... if ( SDHC_IssueCommand( sCh, 61, (u32)((1<<31)|uBlocks), SDHC_CMD_ADTC_TYPE, SDHC_RES_R1B_TYPE) == FALSE ) { return FALSE; } while( sCh->m_uRemainBlock != 0 ); // wait CCS signal. while( sCh->m_uCCSResponse == 0x1 || sCh->m_uCCSResponse == 0x2 ); Outp16( sCh->m_uBaseAddr+SDHC_TRANS_MODE, (Inp16(sCh->m_uBaseAddr+SDHC_TRANS_MODE)&~(0x3<<8))|(0x2<<8)); Outp32( sCh->m_uBaseAddr+SDHC_CONTROL2, Inp32(sCh->m_uBaseAddr+SDHC_CONTROL2)&(~(1<<11)) ); // SDHC_CeATAGetStatus( sCh );// if ( SDHC_SetCeATATaskFile(sCh, SDHC_ATCMD_STANDBY_IMM, 0, 0, &taskFile) == FALSE ) {// return FALSE;// }// if ( SDHC_SetCeATATaskFile(sCh, SDHC_ATCMD_FLUSH_CACHE_EXT, 0, 0, &taskFile) == FALSE ) {// return FALSE;// } return TRUE;}//////////// File Name : SDHC_WriteBlocks// File Description : This function writes user-data common usage.// Input : start block, block count, source buffer address, SDHC channel// Output : Success or Failurebool SDHC_WriteBlocks(u32 uStBlock, u16 uBlocks, u32 uBufAddr, SDHC* sCh) { u32 i; if( sCh->m_eCardType == SDHC_CE_ATA_CARD ) { return SDHC_CEATAWriteBlocks( uStBlock, uBlocks, uBufAddr, sCh ); } if(sCh->m_eTransMode == SDHC_BYTE_MODE) uStBlock = uStBlock<<9; // uStBlock * 512; sCh->m_uRemainBlock = uBlocks; // number of blocks. sCh->m_uBufferPtr = (u32*)uBufAddr; if ( !SDHC_WaitForCard2TransferState( sCh ) ) return FALSE; if ( sCh->m_eOpMode == SDHC_INTERRUPT_MODE ) { INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fWriteFn ); } else if ( sCh->m_eOpMode == SDHC_DMA_MODE ) { INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn ); INTC_Enable( sCh->m_ucIntChannelNum ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE, Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE)| SDHC_BUFFER_READREADY_SIG_INT_EN| SDHC_BUFFER_WRITEREADY_SIG_INT_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN| SDHC_COMMANDCOMPLETE_SIG_INT_EN ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, SDHC_DMA_SIG_INT_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN); SDHC_SetSystemAddressReg(sCh, (u32)uBufAddr);// AHB System Address For Write } SDHC_SetBlockSizeReg(sCh, 7, 512); // Maximum DMA Buffer Size, Block Size SDHC_SetBlockCountReg(sCh, uBlocks); // Block Numbers to Write SDHC_SetTransferModeReg( (uBlocks==1)?(0):(1), 0, 1, 1, (sCh->m_eOpMode!=SDHC_DMA_MODE)?(0):(1), sCh ); if (uBlocks == 1) { if ( !SDHC_IssueCommand( sCh, 24, uStBlock, SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE )) { return FALSE; } } else { if ( !SDHC_IssueCommand( sCh, 25, uStBlock, SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE )) { return FALSE; } } if ( sCh->m_eOpMode == SDHC_POLLING_MODE ) { while( sCh->m_uRemainBlock != 0 ) { SDHC_WriteOneBlock( sCh, 0 ); } } else if ( sCh->m_eOpMode == SDHC_INTERRUPT_MODE ) { Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE)| SDHC_BUFFER_WRITEREADY_SIG_INT_EN ); INTC_Enable( sCh->m_ucIntChannelNum ); // DMA Interrupt enable; while(sCh->m_uRemainBlock != 0); } else if ( sCh->m_eOpMode == SDHC_DMA_MODE ) { while(sCh->m_uRemainBlock != 0); } // wait for Transfer Complete - SDHC_TRANSFERCOMPLETE_STS_INT_EN if ( sCh->m_eOpMode != SDHC_DMA_MODE ) { // When DMA mode, clear at DMA Done handler. SDHC_INT_WAIT_CLEAR( sCh, 1, i ); } if ( sCh->m_eOpMode == SDHC_INTERRUPT_MODE ) { Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT, Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT )| SDHC_BUFFER_WRITEREADY_SIG_INT_EN ); } else if ( sCh->m_eOpMode == SDHC_DMA_MODE ) { Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT, Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT)| SDHC_DMA_SIG_INT_EN ); } return TRUE;}//////////// File Name : SDHC_WriteBlocksSuspend// File Description : Suspend / Resume Feature Test function.// Input : start block, block count, source buffer address, SDHC channel// Output : Success or Failurebool SDHC_WriteBlocksSuspend(u32 uStBlock, u16 uBlocks, u32 uBufAddr, SDHC* sCh) { u32 i; u32 BackupAddress; u16 BackupBlockSize; u16 BackupBlockCnt; u32 BackupArgument; u16 BackupTransMode; u32 Writed_Count; if(sCh->m_eTransMode == SDHC_BYTE_MODE) uStBlock = uStBlock<<9; // uStBlock * 512; sCh->m_uRemainBlock = uBlocks; // number of blocks. sCh->m_uBufferPtr = (u32*)uBufAddr; // Blockgap Interrupt Enable Outp8( sCh->m_uBaseAddr+SDHC_BLOCKGAP_CTRL, (1<<3) ); INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn ); INTC_Enable( sCh->m_ucIntChannelNum ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE,// Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE)| SDHC_BUFFER_READREADY_SIG_INT_EN| SDHC_BUFFER_WRITEREADY_SIG_INT_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN| SDHC_BLOCKGAP_EVENT_SIG_INT_EN| SDHC_COMMANDCOMPLETE_SIG_INT_EN ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE,// SDHC_BLOCKGAP_EVENT_SIG_INT_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN); SDHC_SetSystemAddressReg(sCh, (u32)uBufAddr);// AHB System Address For Write SDHC_SetBlockSizeReg(sCh, 7, 512); // Maximum DMA Buffer Size, Block Size SDHC_SetBlockCountReg(sCh, uBlocks); // Block Numbers to Write SDHC_SetTransferModeReg( 1, 0, 1, 1, (sCh->m_eOpMode!=SDHC_DMA_MODE)?(0):(1), sCh ); // Multi Block Only if ( !SDHC_IssueCommand( sCh, 25, uStBlock, SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE )) { return FALSE; } // Blockgap Interrupt Enable Outp8( sCh->m_uBaseAddr+SDHC_BLOCKGAP_CTRL, (1<<3)|(1<<0) ); SDHC_INT_WAIT_CLEAR( sCh, 2, i ); // waiting Block Gap // wait until transfer complete. while( sCh->m_uRemainBlock != 0 );// Delay(wait); // Suspend mode. if ( !SDHC_IssueCommand52( sCh, 12, 0, SDHC_CMD_AC_TYPE, SDHC_RES_R1_TYPE, 1/* suspend */ ) ) { return FALSE; } // Backup Status Register printf( "status : %x , error status : %x\n" , Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT), Inp16( sCh->m_uBaseAddr+SDHC_ERROR_INT_STAT) ); printf( "DMA Position : %x, SourcePosition:%x, Difference : %x\n", Inp32( sCh->m_uBaseAddr+SDHC_SYS_ADDR ), uBufAddr, Inp32( sCh->m_uBaseAddr+SDHC_SYS_ADDR )-uBufAddr ); BackupAddress = Inp32( sCh->m_uBaseAddr+SDHC_SYS_ADDR ); BackupBlockSize = Inp16( sCh->m_uBaseAddr+SDHC_BLK_SIZE); BackupBlockCnt = Inp16( sCh->m_uBaseAddr+SDHC_BLK_COUNT); BackupArgument = Inp32( sCh->m_uBaseAddr+SDHC_ARG ); BackupTransMode = Inp16( sCh->m_uBaseAddr+SDHC_TRANS_MODE); Writed_Count = uBlocks - BackupBlockCnt; Outp8( sCh->m_uBaseAddr+SDHC_BLOCKGAP_CTRL, 0/*(1<<3)*/ ); // Resume mode.----------------------------------------------- sCh->m_uRemainBlock = BackupBlockCnt; INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn ); INTC_Enable( sCh->m_ucIntChannelNum ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE, SDHC_BUFFER_READREADY_SIG_INT_EN| SDHC_BUFFER_WRITEREADY_SIG_INT_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN| SDHC_BLOCKGAP_EVENT_SIG_INT_EN| SDHC_COMMANDCOMPLETE_SIG_INT_EN ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, SDHC_TRANSFERCOMPLETE_SIG_INT_EN); SDHC_SetSystemAddressReg(sCh, (u32)BackupAddress);// AHB System Address For Write SDHC_SetBlockSizeReg(sCh, 7, 512); // Maximum DMA Buffer Size, Block Size SDHC_SetBlockCountReg(sCh, BackupBlockCnt); // Block Numbers to Write SDHC_SetTransferModeReg( 1, 0, 1, 1, (sCh->m_eOpMode!=SDHC_DMA_MODE)?(0):(1), sCh ); Delay(10000); // Restore Status Register. Outp32( sCh->m_uBaseAddr+SDHC_SYS_ADDR, BackupAddress); Outp16( sCh->m_uBaseAddr+SDHC_BLK_SIZE, BackupBlockSize); Outp16( sCh->m_uBaseAddr+SDHC_BLK_COUNT, BackupBlockCnt); Outp32( sCh->m_uBaseAddr+SDHC_ARG, BackupArgument ); Outp16( sCh->m_uBaseAddr+SDHC_TRANS_MODE, BackupTransMode); if ( !SDHC_IssueCommand52( sCh, 25, uStBlock+Writed_Count, SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE, 2/* Resume */ ) ) { return FALSE; } while( sCh->m_uRemainBlock != 0 ); printf( "Resume Address : %x, Resume Block Size : %x \n", Inp32(sCh->m_uBaseAddr+SDHC_SYS_ADDR), Inp16(sCh->m_uBaseAddr+SDHC_BLK_COUNT) ); // staus clear.// Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT,// Inp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT)|SDHC_DMA_SIG_INT_EN ); return TRUE;}//////////// File Name : SDHC_CEATAReadBlocks// File Description : This function reads user-data only for CE-ATA.// Input : start block, block count, target buffer address, SDHC channel// Output : Success or Failurebool SDHC_CEATAReadBlocks(u32 uStBlock, u16 uBlocks, u32 uBufAddr, SDHC* sCh) { SDHC_ataTaskFile taskFile; Outp16( sCh->m_uBaseAddr+SDHC_TRANS_MODE, Inp16(sCh->m_uBaseAddr+SDHC_TRANS_MODE)&~(0x3<<8));// while(!SDHC_IssueCommand(sCh, 6, (3<<24)|(191<<16)|((1<<4)<<8), SDHC_CMD_AC_TYPE, SDHC_RES_R1_TYPE ) ); while( SDHC_WaitForCard2TransferState(sCh) == FALSE ); //----------------------------------------------------------------------------- if ( SDHC_SetCeATATaskFile( sCh, SDHC_ATCMD_READ_DMA_EXT, uStBlock, uBlocks, &taskFile ) == FALSE ) { return FALSE; } INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn ); INTC_Enable( sCh->m_ucIntChannelNum ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE, ~(SDHC_DMA_SIG_INT_EN|SDHC_BLOCKGAP_EVENT_SIG_INT_EN) ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, SDHC_DMA_SIG_INT_EN| SDHC_CCS_INTERRUPT_STATUS_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN ); SDHC_SetSystemAddressReg(sCh, (u32)uBufAddr);// AHB System Address For Write SDHC_SetBlockSizeReg(sCh, 7, 512); // Maximum DMA Buffer Size, Block Size SDHC_SetBlockCountReg(sCh, uBlocks); // Block Numbers to Write SDHC_SetTransferModeReg(1, 1, 0, 1, 1, sCh ); sCh->m_uRemainBlock = uBlocks; sCh->m_uBufferPtr = (u32*)uBufAddr; sCh->m_uCCSResponse = 0x1; Outp16( sCh->m_uBaseAddr+SDHC_TRANS_MODE, (Inp16(sCh->m_uBaseAddr+SDHC_TRANS_MODE)&~(0x3<<8))|(sCh->m_uCCSResponse<<8)); Outp32( sCh->m_uBaseAddr+SDHC_CONTROL2, Inp32(sCh->m_uBaseAddr+SDHC_CONTROL2)|(1<<11) ); // Read... if ( SDHC_IssueCommand( sCh, 61, (u32)((0<<31)|uBlocks), SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE) == FALSE ) { return FALSE; } Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE, ~(SDHC_DMA_SIG_INT_EN|SDHC_BLOCKGAP_EVENT_SIG_INT_EN) ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, SDHC_DMA_SIG_INT_EN| SDHC_CCS_INTERRUPT_STATUS_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN ); while( sCh->m_uRemainBlock != 0 ); // wait CCS signal. while( sCh->m_uCCSResponse == 0x1 || sCh->m_uCCSResponse == 0x2 ); Outp32( sCh->m_uBaseAddr+SDHC_CONTROL2, Inp32(sCh->m_uBaseAddr+SDHC_CONTROL2)&(~(1<<11)) ); return TRUE;}//////////// File Name : SDHC_ReadBlocks// File Description : This function reads user-data common usage.// Input : start block, block count, target buffer address, SDHC channel// Output : Success or Failurebool SDHC_ReadBlocks(u32 uStBlock, u16 uBlocks, u32 uBufAddr, SDHC* sCh){ u32 i; if( sCh->m_eCardType == SDHC_CE_ATA_CARD ) { return SDHC_CEATAReadBlocks( uStBlock, uBlocks, uBufAddr, sCh ); } if(sCh->m_eTransMode == SDHC_BYTE_MODE) uStBlock = uStBlock<<9;//*512; sCh->m_uRemainBlock = uBlocks; sCh->m_uBufferPtr=(u32*)uBufAddr; if ( !SDHC_WaitForCard2TransferState( sCh ) ) return FALSE; if ( sCh->m_eOpMode == SDHC_INTERRUPT_MODE ) { INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fReadFn ); } else if ( sCh->m_eOpMode == SDHC_DMA_MODE ) { INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn ); INTC_Enable( sCh->m_ucIntChannelNum ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_STAT_ENABLE, ~(SDHC_DMA_SIG_INT_EN|SDHC_BLOCKGAP_EVENT_SIG_INT_EN) ); Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE, SDHC_DMA_SIG_INT_EN| SDHC_TRANSFERCOMPLETE_SIG_INT_EN); SDHC_SetSystemAddressReg(sCh, (u32)uBufAddr);// AHB System Address For Write } SDHC_SetBlockSizeReg(sCh, 7, 512); // Maximum DMA Buffer Size, Block Size SDHC_SetBlockCountReg(sCh, uBlocks); // Block Numbers to Write SDHC_SetTransferModeReg((uBlocks==1)?(0):(1), 1, 1, 1, (sCh->m_eOpMode!=SDHC_DMA_MODE)?(0):(1), sCh );// 1, (uBlocks==1)?(0):(1), 1, (sCh->m_eOpMode!=SDHC_DMA_MODE)?(0):(1), sCh ); // to do question. if (uBlocks == 1) { // CMD17: Single-Read if ( !SDHC_IssueCommand( sCh, 17, uStBlock, SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE )) { return FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -