⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmcfs.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
//****************************************************************************//// MMCFS.C - File system driver for the external MMC FLASH.//// Copyright (c) 2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"#include "../hwport.h"#include "../hwdefs.h"#include "mmc.h"//****************************************************************************//// The following four values must be defined in the section of hwport.h for// the selected board to tell the MMC code the GPIO being used for the CMD and// DAT pins (this is dependent upon how the MMC card is wired into the board):////     HwPortABCD_MMC_CMD - The bit in the HwPortABCD register for the MMC//                          CMD pin.//         - or -//     HwPortE_MMC_CMD - The bit in the HwPortE register for the MMC CMD pin.////     HwPortABCD_MMC_CMD_Shift - The number of bits to shift the HwPortABCD//                                register value to get the MMC CMD bit in the//                                least significant bit.//         - or -//     HwPortE_MMC_CMD_Shift - The number of bits to shift the HwPortE//                             register value to get the MMC CMD bit in the//                             least significant bit.////     HwPortABCD_MMC_DAT - The bit in the HwPortABCD register for the MMC//                          DAT pin.//         - or -//     HwPortE_MMC_DAT - The bit in the HwPortE register for the MMC DAT pin.////     HwPortABCD_MMC_DAT_Shift - The number of bits to shift the HwPortABCD//                                register value to get the MMC DAT bit in the//                                least significant bit.//         - or -//     HwPortE_MMC_DAT_Shift - The number of bits to shift the HwPortE//                             register value to get the MMC DAT bit in the//                             least significant bit.////****************************************************************************//****************************************************************************//// Determine the register, bit, and shift required to access the command line// of the MMC bus.////****************************************************************************#ifdef HwPortABCD_MMC_CMD#define MMC_CMD_PORT                            HwPortABCD#define MMC_CMD_DIR                             HwDdrABCD#define MMC_CMD_BIT                             HwPortABCD_MMC_CMD#define MMC_CMD_SHIFT                           HwPortABCD_MMC_CMD_Shift#endif#ifdef HwPortE_MMC_CMD#define MMC_CMD_PORT                            HwPortE#define MMC_CMD_DIR                             HwDdrE#define MMC_CMD_BIT                             HwPortE_MMC_CMD#define MMC_CMD_SHIFT                           HwPortE_MMC_CMD_Shift#endif//****************************************************************************//// Determine the register, bit, and shift required to access the data line of// the MMC bus.////****************************************************************************#ifdef HwPortABCD_MMC_DAT#define MMC_DAT_PORT                            HwPortABCD#define MMC_DAT_DIR                             HwDdrABCD#define MMC_DAT_BIT                             HwPortABCD_MMC_DAT#define MMC_DAT_SHIFT                           HwPortABCD_MMC_DAT_Shift#endif#ifdef HwPortE_MMC_DAT#define MMC_DAT_PORT                            HwPortE#define MMC_DAT_DIR                             HwDdrE#define MMC_DAT_BIT                             HwPortE_MMC_DAT#define MMC_DAT_SHIFT                           HwPortE_MMC_DAT_Shift#endif//****************************************************************************//// Only include this code if we have MMC data and command lines defined.////****************************************************************************#if defined(MMC_DAT_PORT) && defined(MMC_CMD_PORT)//****************************************************************************//// A macro to make the MMC command line an output.////****************************************************************************#if MMC_CMD_SHIFT >= 24#define MMCCmdOutput            pulPtr[MMC_CMD_DIR >> 2] &= ~MMC_CMD_BIT#else#define MMCCmdOutput            pulPtr[MMC_CMD_DIR >> 2] |= MMC_CMD_BIT#endif//****************************************************************************//// A macro to make the MMC command line an input.////****************************************************************************#if MMC_CMD_SHIFT >= 24#define MMCCmdInput             pulPtr[MMC_CMD_DIR >> 2] |= MMC_CMD_BIT#else#define MMCCmdInput             pulPtr[MMC_CMD_DIR >> 2] &= ~MMC_CMD_BIT#endif//****************************************************************************//// A macro to make the MMC data line an output.////****************************************************************************#if MMC_DAT_SHIFT >= 24#define MMCDatOutput            pulPtr[MMC_DAT_DIR >> 2] &= ~MMC_DAT_BIT#else#define MMCDatOutput            pulPtr[MMC_DAT_DIR >> 2] |= MMC_DAT_BIT#endif//****************************************************************************//// A macro to make the MMC data line an input.////****************************************************************************#if MMC_DAT_SHIFT >= 24#define MMCDatInput             pulPtr[MMC_DAT_DIR >> 2] |= MMC_DAT_BIT#else#define MMCDatInput             pulPtr[MMC_DAT_DIR >> 2] &= ~MMC_DAT_BIT#endif//****************************************************************************//// The name of these drives.////****************************************************************************static const unsigned short pusDriveName1[] ={    'M', 'u', 'l', 't', 'i', 'M', 'e', 'd', 'i', 'a', 'C', 'a',    'r', 'd', ' ', '1', '\0'};static const unsigned short pusDriveName2[] ={    'M', 'u', 'l', 't', 'i', 'M', 'e', 'd', 'i', 'a', 'C', 'a',    'r', 'd', ' ', '2', '\0'};//****************************************************************************//// The persistent state of the MMC driver.////****************************************************************************static struct{    //    // The number of MMC cards found.    //    unsigned short usNumCards;    //    // The currently selected MMC card.    //    unsigned short usCurrent;    //    // The persistent state of the FAT layer used for the first MMC card.    //    tFAT sFAT1;    //    // The persistent state of the FAT layer used for the second MMC card.    //    tFAT sFAT2;} sMMC;//****************************************************************************//// MMCClock clocks the MMC bus the given number of times.////****************************************************************************static voidMMCClock(unsigned long ulCount){    volatile unsigned long *pulPtr = (unsigned long *)HwMMCAddress;    //    // Loop while there are more clocks cycles to create.    //    while(ulCount--)    {        //        // Clock the MMC bus.        //        *pulPtr = 0;    }}//****************************************************************************//// MMCGetCRC7 computes the CRC7 value for the given MMC command.////****************************************************************************static unsigned charMMCGetCRC7(unsigned char *pucCommand){    unsigned long ulByte, ulBit, ulValue;    unsigned char ucCRC7 = 0;    //    // Loop through the five bytes in the command.    //    for(ulByte = 0; ulByte < 5; ulByte++)    {        //        // Get this byte.        //        ulValue = pucCommand[ulByte];        //        // Loop through the eight bits in this byte.        //        for(ulBit = 0; ulBit < 8; ulBit++)        {            //            // Shift the running CRC7 up by one bit.            //            ucCRC7 <<= 1;            //            // Compute the next iteration of the CRC7.            //            ucCRC7 ^= ((((ulValue << ulBit) ^ ucCRC7) & 0x80) ? 0x09 : 0x00);        }    }    //    // Return the computed CRC7 value.    //    return(ucCRC7 & 0x7f);}//****************************************************************************//// MMCGetCRC16 computes the CRC16 value for the data buffer.////****************************************************************************static unsigned shortMMCGetCRC16(unsigned long *pulBuffer, unsigned long bIsByteSwapped){    unsigned long ulIdx, ulByte, ulBit, ulValue, ulWord;    unsigned short usCRC16 = 0;    //    // Loop through the 128 words in the data buffer.    //    for(ulIdx = 0; ulIdx < 128; ulIdx++)    {        //        // Get this word.        //        ulWord = pulBuffer[ulIdx];        //        // Byte swap this word if it is byte swapped in memory.        //        if(bIsByteSwapped)        {            ulWord = (((ulWord >> 24) & 0x000000ff) |                      ((ulWord >> 8) & 0x0000ff00) |                      ((ulWord << 8) & 0x00ff0000) |                      ((ulWord << 24) & 0xff000000));        }        //        // Loop through the four bytes in this word.        //        for(ulByte = 0; ulByte < 4; ulByte++)        {            //            // Get this byte, shifting it up by eight bits so that it lines up            // with the MSB of the running CRC16.            //            ulValue = (ulWord >> (ulByte * 8)) << 8;            //            // Loop through the eight bits in this byte.            //            for(ulBit = 0; ulBit < 8; ulBit++)            {                //                // Compute the next iteration of the CRC16.                //                if((usCRC16 ^ (ulValue << ulBit)) & 0x8000)                {                    usCRC16 = (usCRC16 << 1) ^ 0x1021;                }                else                {                    usCRC16 <<= 1;                }            }        }    }    //    // Return the computed CRC16 value.    //    return(usCRC16);}//****************************************************************************//// MMCSendCommand constructs and sends a command to the MMC bus.////****************************************************************************static voidMMCSendCommand(unsigned char ucCmd, unsigned long ulArg){    unsigned char ucCommand[6];    //    // Construct the MMC command packet.    //    ucCommand[0] = 0x40 | (ucCmd & 0x3f);    ucCommand[1] = (ulArg & 0xff000000) >> 24;    ucCommand[2] = (ulArg & 0x00ff0000) >> 16;    ucCommand[3] = (ulArg & 0x0000ff00) >> 8;    ucCommand[4] = ulArg & 0x000000ff;    ucCommand[5] = (MMCGetCRC7(ucCommand) << 1) | 0x01;    //    // Send the command packet to the MMC bus.    //    MMCWriteCommand(ucCommand);}//****************************************************************************//// MMCInit initializes the MMC cards, performing isolation of the cards on the// MMC bus and assigning unique relative addresses to each card found.////****************************************************************************static unsigned longMMCInit(void){    volatile unsigned long *pulPtr = (unsigned long *)HwBaseAddress;    unsigned long ulAddress;    unsigned char ucRes[18];    //    // Initially, there are no cards.    //    sMMC.usNumCards = 0;    //    // The maximum MMC clock during enumeration is 400kHz, so slow down the    // clock to meet this spec.    //    pulPtr[HwMMCMemConfig >> 2] &= ~HwMMCMemValue;    //    // Clock the MMC bus for a bit to clear out any residual state.    //    MMCClock(100);    //    // Put the MMC cards into idle mode.    //    MMCSendCommand(GO_IDLE_STATE, 0x00000000);    //    // Clock the MMC bus for a bit.    //    MMCClock(60);    //    // Inform the MMC cards of the operating voltage.    //    do    {        //        // Tell the MMC cards that they will be operating in the 3.1V to 3.2V        // range.        //        MMCSendCommand(SEND_OP_COND, OCR_31_32);        if(MMCReadResponse(ucRes, 6) == 0)        {            //            // No response was read, so there are no MMC cards.            //            return(0);        }        //        // Clock the MMC bus.        //        MMCClock(8);    }    while((ucRes[1] & 0x80) == 0);    //    // Clock the MMC bus.    //    MMCClock(100);    //    // Set the address of the first MMC card found.    //    ulAddress = 0x00010000;    //    // Get the CIDs until we've found all the MMC cards.    //    while(1)    {        //        // Get the CID from the MMC card(s).        //        MMCSendCommand(ALL_SEND_CID, 0x00000000);        //        // Read back the CID.        //        if(MMCReadResponse(ucRes, 17) == 0)        {            break;        }        //        // Clock the MMC bus.        //        MMCClock(8);        //        // Set the relative address of this MMC card.        //        MMCSendCommand(SET_RELATIVE_ADDR, ulAddress);        if(MMCReadResponse(ucRes, 6) == 0)        {            break;        }        //        // Clock the MMC bus.        //        MMCClock(8);        //        // Select this MMC card.        //        MMCSendCommand(SELECT_CARD, ulAddress);        if(MMCReadResponse(ucRes, 6) == 0)        {            break;        }        //        // Clock the MMC bus.        //        MMCClock(8);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -