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

📄 sd_cmd.c

📁 This fat 16 can be used for logging function. The user can use it for logger device.
💻 C
📖 第 1 页 / 共 4 页
字号:
        while((pstr[cntr]) && (cntr <= _FF_MAX_FPRINTF))
        {
            pstr_sram[cntr] = pstr[cntr];
            cntr++;
        }
        pstr_sram[cntr] = 0;

        va_start(arglist, pstr);
        vsprintf(temp_buff, pstr_sram, arglist);
    #endif
    va_end(arglist);

    fp = temp_buff;
    while(*fp)
    {
        #ifdef _IAR_EWAVR_
            if(_FF_putchar(*fp) == (int16) EOF)
                return;
            fp++;
        #else
            if(_FF_putchar(*fp++) == (int16) EOF)
                return;
        #endif
    }
}
#endif  /*_DEBUG_ON_*/


/****************************************************************************
**
** Sends one charater while receiving one character on the SPI bus
**
** Parameters: mydata, character to send
**
** Returns: Received character
**
****************************************************************************/
uint8 _FF_spi(uint8 mydata)
{
    SPDR = mydata;          /* byte 1 */
    while((SPSR&0x80) == 0)
        ;
    return(SPDR);
}


/****************************************************************************
**
** This function is required to initialize the Flash card so reading and 
** writing to the card is possible.  This function also reads the card's 
** partition table and boot sector, storing the card information needed to 
** handle the file system.  No data can be read from or written to the card 
** without this function being run first.
**
** Parameters: NONE
**
** Returns: 1 - Card initialized
**          0 - Initialization failed
**
****************************************************************************/
uint8 initialize_media(void)
{
    int8 n;
    uint32 root_dir_sectors;
    #ifndef _BIG_ENDIAN_
        uint16 part_sector_start;
    #else     /* USE _SMALL_ENDIAN_ */
        HiLo16Union part_sector_start;
    #endif
    HiLo32Union bpb_tot_sectors;
    FAT16BootSectStruct *bpb;
    // initiate spi
    _FF_spi_init();    // no use this function..............

    if(set_SD_mode(SD_SPI))             /* Reset and initialize the card to SPI mode */
        return(0);                      /* SEND COMMAND0 AND COMMAND1 */

    #ifndef _BYTES_PER_SEC_512_ // * COMMAND 512 BYTES PER SECTOR */
        BPB_BytsPerSec.uval16 = 512;    /* Initialize sector size to 512 (all SD cards have a 512 sector size) */
    #endif

    if(_FF_read(0x0, _FF_Buff))    /* READ SECTOR0 FOR FAT PROCESSOR */
    {        
        //*******************************************************************
        #ifdef _DEBUG_ON_
            _FF_printf(_FF_RErrStr);
        #endif
        //*******************************************************************
        _FF_error = INIT_ERR;
        return(0);
    }

    bpb = (FAT16BootSectStruct *) _FF_Buff; 
    /*PROCESS SIGNATURE OF FAT */
    if(bpb->SigWord != SIGNATURE_WORD)    /*0x55AA*/
    {
        /* Location Has to have respective values to be a valid Boot or Partition Sector */
        //*********************************************************************
        #ifdef _DEBUG_ON_
            _FF_printf(_FF_InvParTblStr);
        #endif     
        //**********************************************************************
        _FF_error = INV_PARTTABLE_ERR;
        return(0);
    }
    /*BS_jmpBoot FIELD */
    if(((_FF_Buff[0] == 0xEB) && (_FF_Buff[2] == 0x90)) || (_FF_Buff[0] == 0xE9))
        #ifndef _BIG_ENDIAN_
            part_sector_start = 0;    /* Valid Jump, must be Drive */
        #else
            part_sector_start.uval16 = 0;    /* Valid Jump, must be Drive */
        #endif
    else
    {
        /* Find valid Partition Entry */
        for(n = 0; n < 4; n++)
        {
            if(bpb->PartEnt[n].Starting_Head) /* FSI_Nxt_Free FIELD */
            {
                #ifndef _BIG_ENDIAN_
                    part_sector_start = bpb->PartEnt[n].Starting_Sector.uval16.lo;
                #else
                    part_sector_start.uval8.hi = bpb->PartEnt[n].Starting_Sector.uval8.mh;
                    part_sector_start.uval8.lo = bpb->PartEnt[n].Starting_Sector.uval8.hi;
                #endif
                n = 0x10;
            }
        }
        if(!(n & 0x10))
        {
            #ifndef _BIG_ENDIAN_
                part_sector_start = bpb->PartEnt[0].Starting_Sector.uval16.lo;
            #else
                part_sector_start.uval8.hi = bpb->PartEnt[0].Starting_Sector.uval8.mh;
                part_sector_start.uval8.lo = bpb->PartEnt[0].Starting_Sector.uval8.hi;
            #endif
        }
    }

    /* Store the Sector address of the Start of the Partition */
    #ifndef _BIG_ENDIAN_
        _FF_PartitionAddr = (uint32) part_sector_start;

        if(part_sector_start)
    #else
        _FF_PartitionAddr = (uint32) part_sector_start.uval16;

        if(part_sector_start.uval16)
    #endif
        {
            /* If it is not 0 a new sector has to be read */
            if(_FF_read(_FF_PartitionAddr, _FF_Buff))
            {   //********************************************************************************
                #ifdef _DEBUG_ON_
                    _FF_printf(_FF_RErrStr);
                #endif    
                //********************************************************************************
                _FF_error = INIT_ERR;
                return(0);
            }
            if(!((bpb->SigWord == SIGNATURE_WORD) &&
               (((_FF_Buff[0] == 0xEB) && (_FF_Buff[2] == 0x90)) || (_FF_Buff[0] == 0xE9))))
            {
                /* Location Has to have respective values to be a valid Boot or Partition Sector */
                //*********************************************************************************
                #ifdef _DEBUG_ON_
                    _FF_printf(_FF_InvBootSecStr);
                #endif
                //********************************************************************************
                _FF_error = INV_PARTTABLE_ERR;
                return(0);
            }
        }
     //********************************************************************************************
    #ifdef _DEBUG_ON_
        _FF_printf(_FF_VersionInfoStr);
        _FF_printf(_FF_VERSION_);
        _FF_printf(_FF_BSecStr, _FF_Buff[0],_FF_Buff[1],_FF_Buff[2],_FF_Buff[510],_FF_Buff[511]);
    #endif
     //********************************************************************************************
    /* Get the number of Bytes per Sector (should be 512) */
    #ifdef _BYTES_PER_SEC_512_ /* USE THIS MODE */
        #ifndef _BIG_ENDIAN_
            if(bpb->BytsPerSec != 0x0200)
        #else
            if(bpb->BytsPerSec.uval16 != 0x0002)
        #endif
            {    //*********************************************************************************
                #ifdef _DEBUG_ON_
                    _FF_printf(_FF_ERRStr, 1);
                #endif
                //**********************************************************************************
                return(0);
            }
    #else
        #ifndef _BIG_ENDIAN_
            BPB_BytsPerSec.uval16 = bpb->BytsPerSec;
        #else
            BPB_BytsPerSec.uval8.lo = bpb->BytsPerSec.uval8.hi;
            BPB_BytsPerSec.uval8.hi = bpb->BytsPerSec.uval8.lo;
        #endif
    #endif
    /* Get the number of Sectors per Cluster */
    /*BPB_SecPerClus BYTE 13TH*/
    BPB_SecPerClus = bpb->SecPerClus;
    #if !defined(_BIG_ENDIAN_)
        /* Get the number of Reserved Sectors */
        BPB_RsvdSecCnt.uval16 = bpb->RsvdSecCnt;
        /* Get the number of Root Directory entries (should be 512) */
        BPB_RootEntCnt.uval16 = bpb->RootEntCnt;
        /* Get the FATSz16 value */
        BPB_FATSz16.uval16 = bpb->FATSz16;
        /* Get the number of Total Sectors available */
        if(bpb->TotSec16)
        {
            bpb_tot_sectors.uval16.hi = 0;
            bpb_tot_sectors.uval16.lo = bpb->TotSec16;
        }
        else
        {
            /* If the read value is 0, stored in a different location, read from other location */
            bpb_tot_sectors.uval32 = bpb->TotSec32;
        }
        /* Get the volume's Serial number */
        BS_VolSerial = bpb->VolID;
    #else   /*!defined(_BIG_ENDIAN_)*/
        /* Get the number of Reserved Sectors */
        BPB_RsvdSecCnt.uval8.lo = bpb->RsvdSecCnt.uval8.hi;
        BPB_RsvdSecCnt.uval8.hi = bpb->RsvdSecCnt.uval8.lo;
        /* Get the number of Root Directory entries (should be 512) */
        BPB_RootEntCnt.uval8.lo = bpb->RootEntCnt.uval8.hi;
        BPB_RootEntCnt.uval8.hi = bpb->RootEntCnt.uval8.lo;
        /* Get the FATSz16 value */
        BPB_FATSz16.uval8.lo = bpb->FATSz16.uval8.hi;
        BPB_FATSz16.uval8.hi = bpb->FATSz16.uval8.lo;
        /* Get the number of Total Sectors available */
        if(bpb->TotSec16.uval16)
        {
            bpb_tot_sectors.uval16.hi = 0;
            bpb_tot_sectors.uval8.lo = bpb->TotSec16.uval8.hi;
            bpb_tot_sectors.uval8.ml = bpb->TotSec16.uval8.lo;
        }
        else
        {
            /* If the read value is 0, stored in a different location, read from other location */
            bpb_tot_sectors.uval8.lo = bpb->TotSec32.uval8.hi;
            bpb_tot_sectors.uval8.ml = bpb->TotSec32.uval8.mh;
            bpb_tot_sectors.uval8.mh = bpb->TotSec32.uval8.ml;
            bpb_tot_sectors.uval8.hi = bpb->TotSec32.uval8.lo;
        }
        /* Get the volume's Serial number */
        BS_VolSerial.uval8.lo = bpb->VolID.uval8.hi;
        BS_VolSerial.uval8.ml = bpb->VolID.uval8.mh;
        BS_VolSerial.uval8.mh = bpb->VolID.uval8.ml;
        BS_VolSerial.uval8.hi = bpb->VolID.uval8.lo;
    #endif  /*!defined(_BIG_ENDIAN_)*/
    /* Store the Volume's label */
    //********************************************************************************************* 
    //*********************************************************************************************
    memcpy(BS_VolLab, bpb->VolLab, 11);
    //*********************************************************************************************
    //*********************************************************************************************
    BS_VolLab[11] = 0;        /* Terminate the string */
    /* Calculate the Primary FAT table's Address */
    _FF_Fat1Addr = _FF_PartitionAddr + BPB_RsvdSecCnt.uval16;
    /* Calculate the Secondary FAT table's Address */
    _FF_Fat2Addr = _FF_Fat1Addr + BPB_FATSz16.uval16;
    /* Calculate the Address of the Root Directory */
    _FF_RootAddr = ((uint32) bpb->NumFATs * (uint32) BPB_FATSz16.uval16) + (uint32) BPB_RsvdSecCnt.uval16;
    _FF_RootAddr += _FF_PartitionAddr;

    /* Calculate the number of Total data Clusters */
    #ifdef _BYTES_PER_SEC_512_
        root_dir_sectors = (((uint32) BPB_RootEntCnt.uval16 << 5) + 511) >> 9;
    #else
        root_dir_sectors = (((uint32) BPB_RootEntCnt.uval16 << 5) + BPB_BytsPerSec.uval16 - 1) / BPB_BytsPerSec.uval16;
    #endif

    FirstDataSector = (bpb->NumFATs * BPB_FATSz16.uval16) + BPB_RsvdSecCnt.uval16 + root_dir_sectors;
    /* Find the total number of data clusters (root_dir_sectors is just a temp variable since DataClusTot is a int) */
    root_dir_sectors = (bpb_tot_sectors.uval32 - FirstDataSector) / BPB_SecPerClus;
    Clus0Counter = 2;
    _FF_BuffAddr = 0;

    if(root_dir_sectors < 4085)                /* FAT12 */
        BPB_FATType = 0x32;
    else if(root_dir_sectors < 65525)        /* FAT16 */
        BPB_FATType = 0x36;
    else
    {
        BPB_FATType = 0;
        _FF_error = FAT_ERR; 
        //**********************************************************************************************
        #ifdef _DEBUG_ON_
            _FF_printf(_FF_ERRStr, 2);
        #endif     
        //**********************************************************************************************
        return(0);
    }
    DataClusTot = (uint16) root_dir_sectors;   
    //**************************************************************************************************
    #ifdef _DIRECTORIES_SUPPORTED_
        _FF_DirAddr = _FF_RootAddr;        /* Set current directory to root address */
    #endif
    //
    _FF_FullPath[0] = 0x5C;    /* '\' */
    _FF_FullPath[1] = 0;
    //***************************************************************************************************
    #ifdef _DEBUG_ON_
        #ifdef _BYTES_PER_SEC_512_
            _FF_printf(_FF_BootSecPartAddrStr, (((uint32)_FF_PartitionAddr) << 9));
            _FF_printf(_FF_BPB_BPSStr, 0x200);
        #else
            _FF_printf(_FF_BootSecPartAddrStr, ((uint32) _FF_PartitionAddr * BPB_BytsPerSec.uval16));
            _FF_printf(_FF_BPB_BPSStr, BPB_BytsPerSec.uval16);
        #endif
        _FF_printf(_FF_BPB_SPCStr, BPB_SecPerClus);
        _FF_printf(_FF_BPB_RSCStr, BPB_RsvdSecCnt.uval16);
        _FF_printf(_FF_BPB_NFATStr, bpb->NumFATs);
        _FF_printf(_FF_BPB_RECStr, BPB_RootEntCnt.uval16);
        _FF_printf(_FF_BPB_Fz16Str, BPB_FATSz16.uval16);
        _FF_printf(_FF_BPB_TS16Str, bpb_tot_sectors.uval32);
        _FF_printf(_FF_BPB_FTStr);
    #endif
    //****************************************************************************************************
    if((BPB_FATType != 0x32) && (BPB_FATType != 0x36))
    {   //*************************************************************************************************
        #ifdef _DEBUG_ON_
            _FF_printf(_FF_ERRStr, 3);
        #endif           
        //*************************************************************************************************
        return(0);
    }
    //******************************************************************************************************
    #ifdef _DEBUG_ON_
        else
            _FF_printf(_FF_1CStr, BPB_FATType);
        _FF_printf(_FF_CCntStr, DataClusTot);
        #ifdef _BYTES_PER_SEC_512_
            _FF_printf(_FF_RAddrStr, _FF_RootAddr<<9);
            _FF_printf(_FF_F2AddrStr, _FF_Fat2Addr<<9);
        #else
            _FF_printf(_FF_RAddrStr, _FF_RootAddr * BPB_BytsPerSec.uval16);
            _FF_printf(_FF_F2AddrStr, _FF_Fat2Addr * BPB_BytsPerSec.uval16);
        #endif
        _FF_printf(_FF_RDSecStr, root_dir_sectors);
        _FF_printf(_FF_FDSecStr, FirstDataSector);
    #endif
    //******************************************************************************************************
    //*****************************************************************************************************
    #ifdef _NO_MALLOC_
        /* Verify that all of the file Structure information is cleared */
        for(n = 0; n < _FF_MAX_FILES_OPEN; n++)
        //**************************************************************************************************
            memset(&_FF_FileSpaceAllocation[n], 0x00, sizeof(FILE));
        //**************************************************************************************************    
    #endif
    //******************************************************************************************************
    return(1);
}


/****************************************************************************
**
** Resets the SD card, and either puts it into SPI mode or IDLE mode

⌨️ 快捷键说明

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