📄 sd_driver.c
字号:
/******************************************************************************
*
* (c) copyright Freescale Semiconductor Hong Kong Ltd 2004
* ALL RIGHTS RESERVED
*
*******************************************************************************
** THIS CODE IS ONLY INTENDED AS AN EXAMPLE FOR DEMONSTRATING THE FREESCALE **
** MICROCONTROLLERS. IT HAS ONLY BEEN GIVEN A MIMIMUM LEVEL OF TEST. IT IS **
** PROVIDED 'AS SEEN' WITH NO GUARANTEES AND NO PROMISE OF SUPPORT. **
*******************************************************************************
*
* FILE: sd_driver.c REVISION 0.1
*
* DESCRIPTION: This module handles the major part of SD Driver module,
* (APIs & Functions) applicaton tasks for the system
*
* NOTES: All modules remain at their reset addresses
*
* UPDATED HISTORY:
*
* REV YYYY.MM.DD AUTHOR DESCRIPTION OF CHANGE
* --- ---------- ------ ---------------------
* 0.0 2004.03.01 Taine Chang Initial version
* 0.1 2004.04.12 Derek Lau
* Kenny Lam Demo version
*
******************************************************************************/
/* Freescale is not obligated to provide any support, upgrades or new */
/* releases of the Software. Freescale may make changes to the Software at */
/* any time, without any obligation to notify or provide updated versions of */
/* the Software to you. Freescale expressly disclaims any warranty for the */
/* Software. The Software is provided as is, without warranty of any kind, */
/* either express or implied, including, without limitation, the implied */
/* warranties of merchantability, fitness for a particular purpose, or */
/* non-infringement. You assume the entire risk arising out of the use or */
/* performance of the Software, or any systems you design using the software */
/* (if any). Nothing may be construed as a warranty or representation by */
/* Freescale that the Software or any derivative work developed with or */
/* incorporating the Software will be free from infringement of the */
/* intellectual property rights of third parties. In no event will Freescale */
/* be liable, whether in contract, tort, or otherwise, for any incidental, */
/* special, indirect, consequential or punitive damages, including, but not */
/* limited to, damages for any loss of use, loss of time, inconvenience, */
/* commercial loss, or lost profits, savings, or revenues to the full extent */
/* such may be disclaimed by law. The Software is not fault tolerant and is */
/* not designed, manufactured or intended by Freescale for incorporation */
/* into products intended for use or resale in on-line control equipment in */
/* hazardous, dangerous to life or potentially life-threatening environments */
/* requiring fail-safe performance, such as in the operation of nuclear */
/* facilities, aircraft navigation or communication systems, air traffic */
/* control, direct life support machines or weapons systems, in which the */
/* failure of products could lead directly to death, personal injury or */
/* severe physical or environmental damage (High Risk Activities). You */
/* specifically represent and warrant that you will not use the Software or */
/* any derivative work of the Software for High Risk Activities. */
/* Freescale and the Freescale logos are registered trademarks of Freescale */
/* Semiconductor Inc. */
/*****************************************************************************/
#include "FreescaleDef.h" // Get my definitions (Constants & Macros)
#include "mk_extern.h" // Get Mini-Kernel global prototypes
#include "sd_includes.h" // Get ATA Driver Configuration
#include "usbms_includes.h" // Get ATA Driver Configuration
#include "sd_extern.h"
#include "UF32reg.h"
#include "utl_includes.h"
// code is placed in the main code area.
#pragma CODE_SEG DEFAULT
// ==================================================================
// SD_QUE_ReadMultipleBlock() -
//
// Read single block from SD card
//
// Input - 32-bits block addres (byte)
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
mErrorCode SD_QUE_ReadMultipleBlock(muint32 SD_BlockAddress, muint16 SD_NoOfBlocks)
{
muint16 SD_BlockAdrs_H, SD_BlockAdrs_L,/* j,*/ k, kSD_NoOfBlocksCounter;
muint16 kSD_Temp;
// mint16 *kSD_RxData1;
muint32 i;
gSD_SDSATAT=0;
for(i=0; i<SD_TimeOut; i++)
{
kSD_Temp = SD_CheckStatus();
if(kSD_Temp == 1) // device is ready
break;
}
if((i==SD_TimeOut) && (kSD_Temp == 0) )
return(2);
SD_SDINTREN = 0x001c; // disable CD int
SD_SDBLKLN = 0x0200; // set block length to 512 bytes
SD_SDNOBLK = SD_NoOfBlocks; // Number of blocks
kSD_NoOfBlocksCounter = 0;
SD_BlockAddress *= 512;
SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);
k=0;
if(!gSD_SDcard)
SD_SendCommand(0x0012, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0425); //CMD18 READ_MULTIPLE_BLOCK, data adrs
else
SD_SendCommand(0x0012, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0625); //CMD18 READ_MULTIPLE_BLOCK, data adrs, WBUS
i = 0;
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
i++;
if(i==SD_TimeOut)
return(2);
}
SD_QIEN = 1;
// while (QCDCT34);
i = 0;
while(!(gSD_SDSATAT&0x0100)) // wait for DTDN=1
{
i++;
if(i==SD_TimeOut)
return(2);
}
gSD_SDSATAT=0;
k=0;
SD_SendCommand(0x000C, 0, 0, 0x0061); //CMD12, STOP_TRANSMISSION,
i = 0;
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
i++;
if(i==SD_TimeOut)
return(2);
}
SD_QIEN=0;
return(kSDNoError);
}
// ==================================================================
// SD_QUE_ReadSingleBlock() -
//
// Read single block from SD card via QUE
//
// Input - 32-bits block addres (byte)
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
mErrorCode SD_QUE_ReadSingleBlock(muint32 SD_BlockAddress)
{
muint16 SD_BlockAdrs_H, SD_BlockAdrs_L;
// muint32 i,
muint32 k=0;
gSD_SDSATAT=0;
SD_BlockAddress *=512;
SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);
if(gSD_SDcard) // Plugged flash card is SD
SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0205); //CMD17 READ_SINGLE_BLOCK, data adrs, WBUS for SD card
else
SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0005); //CMD17 READ_SINGLE_BLOCK, data adrs, 1-bit mode for MMC
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
k++;
if(k>100000)
return(1);
}
SD_SDINTREN = 0x001c; // disable CD int
SD_QIEN=1;
k=0;
while(!(gSD_SDSATAT&0x0100)) // wait for DTDN=1
{
k++;
if(k>100000)
return(2);
}
SD_QIEN=0;
return(0);
}
// SD_QUE_ReadSingleBlock() -
//
// Read single block from SD card via QUE
//
// Input - 32-bits block addres (byte)
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
mErrorCode SD_QUE_ReadSingleBlock_FS(muint32 SD_BlockAddress)
{
muint16 SD_BlockAdrs_H, SD_BlockAdrs_L;
// muint32 i,
muint32 k=0;
gSD_SDSATAT=0;
// QUE initialization for SD Rx
IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
mSetBit(QnPRST, QC3CR); // reset QC3
QC3CR=0x1f; //0x1d; //
QC3SZB=0x3f;
QC3REQ=0x01; // USB Tx channel
QC4REQ=0x08; // SD Rx channel
mSetBit(DBRST,QC34DCR); // reset QC34
QC34DTR = 0; // Enable force handshake
SD_BlockAddress *=512;
SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);
if(gSD_SDcard) // Plugged flash card is SD
SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0205); //CMD17 READ_SINGLE_BLOCK, data adrs, WBUS for SD card
else
SD_SendCommand(0x0011, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x0005); //CMD17 READ_SINGLE_BLOCK, data adrs, 1-bit mode for MMC
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
k++;
if(k>100000)
return(1);
}
SD_SDINTREN = 0x001c; // disable CD int
SD_QIEN=1;
mUSBClearBit(USBTCIE,UEPCSR5A); // disable PhyEP5 Xfer complete int
USBMS_SetPhyEP5(64);
k=0;
while(!(gSD_SDSATAT&0x0100)) // wait for DTDN=1
{
k++;
if(k>100000)
return(2);
}
SD_QIEN=0;
return(0);
}
// ==================================================================
// SD_QUE_WriteSingleBlockFromQram2Card() -
//
// Read out single block from Qram
//
// Input - 32-bits block addres (byte)
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
/*mErrorCode SD_QUE_WriteSingleBlockFromQram2Card(muint32 SD_BlockAddress)
{
muint16 SD_BlockAdrs_H, SD_BlockAdrs_L, k=0;
muint16 kSD_Temp;
muint32 kSD_BlockAddress, i, j;
for(i=0; i<SD_TimeOut; i++)
{
kSD_Temp = SD_CheckStatus();
if(kSD_Temp == 1) // device is ready
break;
}
if((i==SD_TimeOut) && (kSD_Temp == 0) )
return(1);
// SD_BlockAddressInWritePage = SD_BlockAddress;
// kSD_BlockAddress = SD_BlockAddressInWritePage*512;
kSD_BlockAddress = kSD_BlockAddress*512;
SD_BlockAdrs_H = (muint16)((kSD_BlockAddress & 0xFFFF0000) >>16);
SD_BlockAdrs_L = (muint16)(kSD_BlockAddress & 0x0000FFFF);
if(!gSD_SDcard)
SD_SendCommand(0x0018, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x004D); //CMD24, WRITE_BLOCK, data adrs, WRD=DATAEN=1 R1
else
SD_SendCommand(0x0018, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x020D); //CMD24, WRITE_BLOCK, data adrs, WRD=DATAEN=1 R1
i = 0;
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
i++;
if(i==SD_TimeOut)
return(2);
}
SD_QIEN=1;
i = 0;
while(!(gSD_SDSATAT&0x0100)) // wait for DTDN=1
{
i++;
if(i==SD_TimeOut)
return(3);
}
j = 0;
while(!(gSD_SDSATAT&0x0200)) // wait for WRDN=1
{
j++;
if(j==SD_TimeOut)
return(4);
}
SD_QIEN=0;
// kSD_errorCheck =SD_CheckResponse();
return(0); // command passed
}
*/
// ==================================================================
// SD_QUE_WriteMultipleBlock() -
//
// Write single block with 0 ~ 255 to SD card
//
// Input - 32-bits block addres (byte)
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
mErrorCode SD_QUE_WriteMultipleBlock(muint32 SD_BlockAddress, muint16 SD_NoOfBlocks)
{
muint16 SD_BlockAdrs_H, SD_BlockAdrs_L, k=0, kSD_Temp;
// muint8 kSD_CheckWriteProtect;
// muint32 kSD_BlockAddress,
muint32 i, j;
muint8 error;
error = 0;
gSD_SDSATAT=0;
// kSD_CheckWriteProtect = SD_CheckWriteProtect();
// if(kSD_CheckWriteProtect)
// return(1); // Write Protect is enabled
for(i=0; i<SD_TimeOut; i++)
{
kSD_Temp = SD_CheckStatus();
if(kSD_Temp == 1) // device is ready
break;
}
if((i==SD_TimeOut) && (kSD_Temp == 0) )
return(1);
SD_BlockAddress *= 512;
SD_SDNOBLK = SD_NoOfBlocks; // Number of blocks
SD_BlockAdrs_H = (muint16)((SD_BlockAddress & 0xFFFF0000) >>16);
SD_BlockAdrs_L = (muint16)(SD_BlockAddress & 0x0000FFFF);
if(!gSD_SDcard) // for 1-bit mode
SD_SendCommand(0x0019, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x042D); //CMD25, WRITE_MULTUPLE_BLOCK, data adrs, WRD=DATAEN=1 R1
else // for 4-bits mode
SD_SendCommand(0x0019, SD_BlockAdrs_H, SD_BlockAdrs_L, 0x062D); //CMD25, WRITE_MULTUPLE_BLOCK, data adrs, WRD=DATAEN=1 R1, WBUS
i = 0;
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
i++;
if(i==SD_TimeOut)
return(2);
}
DisableInterrupts;
SD_QIEN=1;
while(QCDCT12>0); // wait for the last block is sent
SD_LBUF = 1;
EnableInterrupts;
i = 0;
while(!(gSD_SDSATAT&0x0100)) // wait for DTDN=1
{
i++;
if (i == 0x2000)
// if(i==SD_TimeOut)
// return(3);
{
error = 3;
break;
}
}
j = 0;
while(!(gSD_SDSATAT&0x0200)) // wait for WRDN=1
{
j++;
if(j==SD_TimeOut)
{
error = 4;
break;
}
}
SD_LBUF = 0; // reset last buffer in SDCON
SD_QIEN=0;
gSD_SDSATAT=0;
SD_SendCommand(0x000C, 0, 0, 0x0001); //CMD12, STOP_TRANSMISSION,
i = 0;
while(!(gSD_SDSATAT&0x0400)) // wait for cmd end
{
i++;
if(i==SD_TimeOut)
return(5);
}
for(i=0; i<1000; i++)
{
kSD_Temp =(muint16)SD_CheckStatus();
if(kSD_Temp) // return=0, bit8=1 means the card is ready
return(0); // no error
}
return(error);
}
// ==================================================================
// SD_PreInit() -
//
// Step 1. Pre-initialize the flash card
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
void SD_PreInit(void)
{
muint16 i;
// VREG_U = 0x02; // turn on the 3.3V regulator for MPW2
for(i=0;i<9000;i++) // Waiting for 9 ms after power-on
asm nop;
// SD_SDEN = 0; // make sure the SDEN is off before starting
// SD_SDCON = 0x0009; // SDEN, PUEN = 1, for MMC testing
// for(i=0; i<1000; i++) // wait 1ms for start-up
// asm NOP;
/*
SD_IRST = 1; // reset SDHC
for(i=0;i<9000;i++) // Waiting for 9 ms
asm nop;
SD_IRST = 0; // disable reset
for(i=0;i<900;i++) // Waiting for 9 ms
asm nop;
*/
SD_SDCON = 0x0009; // SDEN, PUEN = 1, for MMC testing
for(i=0; i<1000; i++) // wait 1ms for start-up
asm NOP;
UTL_Delay(10);
SD_SDCLKCON = 0x000f; // card clk enable, 1/10, 1.2MHz
SD_SDRDTOUT = 0x5B68; // Set read timeout
// SD_SDRDTOUT = 0x2DB4; // Set read timeout
// SD_CDIE = 1; // enable CD interrupt, remarked for MMC
// while(!SD_CD); // wait for card inserted
//-----------------
// enable all interrupts except timeout error
// SD_SDINTREN = 0x003c; // enable all interrupt, except CRCIE & TOIE
SD_SDINTREN = 0x001c; // enable all interrupt, except SDIE, CRCIE & TOIE
//-----------------
// reset SD card
SD_SendCommand(0, 0, 0, 0); // cmd0
// for(i=0; i<100; i++) // delay 500us for next card init
// for(i=0; i<200; i++) // delay 1ms for next card init, same as CR
for(i=0; i<2000; i++) // delay 8ms for next card init
asm NOP;
SD_SendCommand(55, 0, 0, 1); // APP_CMD, for release all app_cmd
for(i=0; i<2000; i++) // delay 8ms for next card init
asm NOP;
}
// ==================================================================
// SD_Identification() -
//
// Step 2, to idientify whether the card is SD or MMC
//
// Input - nil
//
// Output - nil
//
// If the card is MMC: gSD_SDcard=0, 1 bit mode
// If the card is SD : gSD_SDcard=1, switch to 4-bits mode
//
// ==================================================================
muint8 SD_Identification(void)
{
muint16 i;
muint32 kSD_OCR_H=0, kSD_OCR_M=0, kSD_OCR_L=0, kSD_OCR=0;
muint32 kSD_loop_counter=0;
gSD_SDSATAT = 0;
//-------------
// Send cmd1 to check is it a MMC
SD_SendCommand(0x0001, 0x80FF, 0x8000, 0x0003); // CMD1 SEND_OP_COND, for MMC initializtion
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -