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