Buen dia foreros, quiero saber si alguien a utilizado la libreria FAT de Freescale para manejar la memoria SD con el JM60.
Llevo 15 dias estudiándola, por ahora solo he podido crear archivos y leer solo TXT, ya que las imágenes no las lee.
Lo que quiero es encontrar la forma de leer un archivo y enviarlo por serial.
Tengo entendido que el driver lee por sectores de 512 bytes, pero no he podido lograr saber en punto del programa lo hace.
Comparto los codigos por si les sirven y me pueden ayudar. Gracias.
/**************************CODIGO FAT.C*************************************************************
/* Includes */
#include "Fat.h"
/* File Handlers */
WriteRHandler WHandler;
ReadRHandler RHandler;
/* File Buffers */
UINT8 ag8FATReadBuffer[512];
UINT8 ag8FATWriteBuffer[512];
/* Global Variables */
UINT16 u16FAT_Sector_Size;
UINT16 u16FAT_Cluster_Size;
UINT16 u16FAT_FAT_BASE;
UINT16 u16FAT_Root_BASE;
UINT16 u16FAT_Data_BASE;
UINT16 u16Main_Offset=0;
/***************************************************************************************/
UINT32 LWordSwap(UINT32 u32DataSwap)
{
UINT32 u32Temp;
u32Temp= (u32DataSwap & 0xFF000000) >> 24;
u32Temp+=(u32DataSwap & 0xFF0000) >> 8;
u32Temp+=(u32DataSwap & 0xFF00) << 8;
u32Temp+=(u32DataSwap & 0xFF) << 24;
return(u32Temp);
}
/***************************************************************************************/
void FAT_Read_Master_Block(void)
{
MasterBoot_Entries *pMasterBoot;
while(ag8FATReadBuffer[0]!= 0xEB && ag8FATReadBuffer[1]!=0x3C && ag8FATReadBuffer[2]!=0x90)
{
GetPhysicalBlock(u16Main_Offset++,&ag8FATReadBuffer[0]);
}
u16Main_Offset--;
pMasterBoot=(MasterBoot_Entries*)ag8FATReadBuffer;
u16FAT_Cluster_Size=pMasterBoot->SectorsPerCluster;
u16FAT_Sector_Size=ByteSwap(pMasterBoot->BytesPerSector);
u16FAT_FAT_BASE= u16Main_Offset+ByteSwap(pMasterBoot->ReservedSectors);
u16FAT_Root_BASE= (ByteSwap(pMasterBoot->SectorsPerFat)<<1)+u16FAT_FAT_BASE;
u16FAT_Data_BASE= (ByteSwap(pMasterBoot->RootDirectoryEntries) >>4)+u16FAT_Root_BASE;
}
/***************************************************************************************/
/*void FAT_LS(void)
{
UINT8 u8Counter;
root_Entries *sFileStructure;
GetPhysicalBlock(u16FAT_Root_BASE,ag8FATReadBuffer);
sFileStructure = (root_Entries*)&ag8FATReadBuffer[RootEntrySize];
while(sFileStructure->FileName[0]!=FILE_Clear)
{
if(sFileStructure->FileName[0]!=FILE_Erased)
{
Terminal_Send_String((UINT8*)"\r\n");
for(u8Counter=0;u8Counter<8;u8Counter++)
if(sFileStructure->FileName[u8Counter]!=' ')
Terminal_Send_Byte(sFileStructure->FileName[u8Counter]);
Terminal_Send_Byte('.');
for(u8Counter=0;u8Counter<3;u8Counter++)
if(sFileStructure->Extension[u8Counter]!=' ')
Terminal_Send_Byte(sFileStructure->Extension[u8Counter]);
}
sFileStructure++;
}
}
*/
/***************************************************************************************/
void FAT_FileClose(void)
{
root_Entries *sFileStructure;
UINT16 *pu16FATPointer;
UINT8 u8Counter;
UINT32 u32Sector;
UINT16 u16Offset;
/* Directory Entry*/
u32Sector=WHandler.Dir_Entry/(u16FAT_Sector_Size>>5);
u16Offset=WHandler.Dir_Entry%(u16FAT_Sector_Size>>5);
GetPhysicalBlock(u16FAT_Root_BASE+u32Sector,ag8FATReadBuffer);
sFileStructure=(root_Entries*)ag8FATReadBuffer;
sFileStructure+=u16Offset;
// FileName
for(u8Counter=0;u8Counter<8;u8Counter++)
sFileStructure->FileName[u8Counter]=WHandler.FileName[u8Counter];
// Entension
for(u8Counter=0;u8Counter<3;u8Counter++)
sFileStructure->Extension[u8Counter]=WHandler.Extension[u8Counter];
// Attributes
sFileStructure->Attributes=0x20;
sFileStructure->_Case=0x18;
sFileStructure->MiliSeconds=0xC6;
// Date & Time Information
sFileStructure->CreationTime=0x2008;
sFileStructure->CreationDate=0x2136;
sFileStructure->AccessDate=0x2136;
sFileStructure->ModificationTime=0x2008;
sFileStructure->ModificationDate=0x2136;
// Fat entry and file Size
sFileStructure->ClusterNumber=ByteSwap(WHandler.BaseFatEntry);
sFileStructure->SizeofFile=LWordSwap(WHandler.File_Size);
StorePhysicalBLock(u16FAT_Root_BASE+u32Sector,ag8FATReadBuffer)
/* FAT Table */
u32Sector=WHandler.CurrentFatEntry/(u16FAT_Sector_Size>>1);
u16Offset=WHandler.CurrentFatEntry%(u16FAT_Sector_Size>>1);
GetPhysicalBlock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer);
pu16FATPointer=(UINT16*)ag8FATReadBuffer;
pu16FATPointer+=u16Offset;
*pu16FATPointer=0xFFFF; // Write Final Cluster
StorePhysicalBLock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer)
}
/***************************************************************************************/
UINT16 FAT_SearchAvailableFAT(UINT16 u16CurrentFAT)
{
UINT16 *pu16DataPointer;
UINT16 u16FatEntry=0;
UINT16 u16Sector=0;
UINT16 u16byteSector;
UINT16 u16SectorSize=0;
u16Sector=u16FAT_FAT_BASE;
while(u16Sector < (((u16FAT_Root_BASE-u16FAT_FAT_BASE)>>1)+u16Main_Offset))
{
GetPhysicalBlock(u16Sector++,ag8FATReadBuffer);
pu16DataPointer=(UINT16*)ag8FATReadBuffer;
u16byteSector=0;
u16SectorSize = ((u16FAT_Sector_Size)>> 1);
while(u16byteSector<u16SectorSize)
{
if(*pu16DataPointer==0x0000)
if(u16FatEntry!=u16CurrentFAT)
return(u16FatEntry);
pu16DataPointer++;
u16FatEntry++;
u16byteSector++;
}
}
return(0); // Return 0 if no more FAT positions available
}
/***************************************************************************************/
UINT16 FAT_Entry(UINT16 u16FatEntry,UINT16 u16FatValue, UINT8 u8Function)
{
UINT16 *pu16DataPointer;
UINT16 u16Block;
UINT8 u8Offset;
u16Block = u16FatEntry / (u16FAT_Sector_Size>>1);
u8Offset = (UINT8)(u16FatEntry % (u16FAT_Sector_Size >>1));
GetPhysicalBlock(u16FAT_FAT_BASE+u16Block,ag8FATReadBuffer);
pu16DataPointer=(UINT16*)ag8FATReadBuffer;
pu16DataPointer+=u8Offset;
if(u8Function==NEXT_ENTRY)
return(ByteSwap(*pu16DataPointer));
if(u8Function==WRITE_ENTRY)
{
*pu16DataPointer=ByteSwap(u16FatValue);
StorePhysicalBLock(u16FAT_FAT_BASE+u16Block,ag8FATReadBuffer);
return(0x00);
}
}
/***************************************************************************************/
void FAT_FileWrite(UINT8 *pu8DataPointer,UINT32 u32Size)
{
UINT32 u32SectorToWrite;
UINT8 *pu8ArrayPointer;
UINT16 u16TempFat;
UINT8 u8ChangeSector=1;
while(u32Size)
{
if(u8ChangeSector)
{
u32SectorToWrite= u16FAT_Data_BASE + WHandler.ClusterIndex + (WHandler.CurrentFatEntry-2)*u16FAT_Cluster_Size;
GetPhysicalBlock(u32SectorToWrite,ag8FATWriteBuffer);
pu8ArrayPointer=ag8FATWriteBuffer+WHandler.SectorIndex;
u8ChangeSector=0;
}
while(WHandler.SectorIndex<u16FAT_Sector_Size && u32Size)
{
u32Size--;
WHandler.SectorIndex++;
WHandler.File_Size++;
*pu8ArrayPointer++=*pu8DataPointer++;
}
StorePhysicalBLock(u32SectorToWrite,ag8FATWriteBuffer); // Write Buffer to Sector
/* Check Sector Size */
if(WHandler.SectorIndex == u16FAT_Sector_Size)
{
WHandler.SectorIndex=0;
WHandler.ClusterIndex++;
u8ChangeSector=1;
}
/* Check Cluster Size */
if(WHandler.ClusterIndex == u16FAT_Cluster_Size)
{
//_BGND;
WHandler.ClusterIndex=0;
u16TempFat=FAT_SearchAvailableFAT(WHandler.CurrentFatEntry);
if(!u16TempFat)
_BGND;
(void)FAT_Entry(WHandler.CurrentFatEntry,u16TempFat,WRITE_ENTRY);
WHandler.CurrentFatEntry=u16TempFat;
u8ChangeSector=1;
}
}
}
/***************************************************************************************/
UINT16 FAT_FileRead(UINT8 *pu8UserBuffer)
{
UINT32 u32SectorToRead;
UINT16 u16BufferSize;
if(RHandler.File_Size==0)
return(0);
//_BGND;
u32SectorToRead= u16FAT_Data_BASE + ((RHandler.FAT_Entry-2)*u16FAT_Cluster_Size)+RHandler.SectorOffset;
GetPhysicalBlock(u32SectorToRead,pu8UserBuffer);
if(RHandler.File_Size > u16FAT_Sector_Size)
{
RHandler.File_Size-=u16FAT_Sector_Size;
u16BufferSize=512;
}
else
{
u16BufferSize=(UINT16)RHandler.File_Size;
RHandler.File_Size=0;
}
if(RHandler.SectorOffset < (u16FAT_Cluster_Size)-1)
RHandler.SectorOffset++;
else
{
RHandler.SectorOffset=0;
RHandler.FAT_Entry = FAT_Entry(RHandler.FAT_Entry,0,NEXT_ENTRY); // Get Next FAT Entry
}
return(u16BufferSize);
}
/***************************************************************************************/
void FAT_FileNameOrganizer(UINT8 *pu8FileName,UINT8 *pu8Destiny)
{
UINT8 u8Counter=0;
while(u8Counter<12)
{
if(*pu8FileName != '.')
*pu8Destiny++=*pu8FileName++;
else
{
if(u8Counter<

*pu8Destiny++=0x20;
else
pu8FileName++;
}
u8Counter++;
}
}
/***************************************************************************************/
UINT8 FAT_FileOpen(UINT8 *pu8FileName,UINT8 u8Function)
{
UINT16 u16Temporal;
UINT8 u8FileName[11];
UINT8 u8Counter=0;
UINT8 u8Flag=False;
UINT16 u16Index;
UINT16 u16Block;
UINT16 u16BlockNum=u16FAT_Data_BASE-u16FAT_Root_BASE;
UINT8 u8ErrorCode=ERROR_IDLE;
UINT8 *pu8Pointer;
UINT16 *pu16FATPointer;
UINT32 u32Sector;
UINT16 u16Offset;
root_Entries *sFileStructure;
FAT_FileNameOrganizer(pu8FileName,&u8FileName[0]);
u16Block=0;
while(u16Block < u16BlockNum && u8ErrorCode==ERROR_IDLE)
{
GetPhysicalBlock(u16FAT_Root_BASE+u16Block,ag8FATReadBuffer);
sFileStructure = (root_Entries*)ag8FATReadBuffer;
u16Index=0;
while(u16Index<u16FAT_Sector_Size && u8ErrorCode==ERROR_IDLE)
{
/* If Read or Modify Function */
if(u8Function==READ || u8Function==MODIFY|| u8Function==DELETE || u8Function==OVERWRITE)
{
if(sFileStructure->FileName[0]==FILE_Clear)
u8ErrorCode=FILE_NOT_FOUND;
if(sFileStructure->FileName[0] == u8FileName[0])
{
u8Flag=True;
u8Counter=0;
while(u8Flag==True && u8Counter < 10)
{
u8Counter++;
if(sFileStructure->FileName[u8Counter] != u8FileName[u8Counter])
u8Flag=False;
}
if(u8Flag==True)
{
/* If Read Function */
if(u8Function==READ)
{
RHandler.Dir_Entry=(u16Block*EntriesPerBlock)+((u16Index)/RootEntrySize);
RHandler.File_Size=LWordSwap(sFileStructure->SizeofFile);
RHandler.FAT_Entry=ByteSwap(sFileStructure->ClusterNumber);
RHandler.SectorOffset=0;
u8ErrorCode=FILE_FOUND;
}
/*If Delete Function //Leandro Martinez*/
else if(u8Function==DELETE)
{
WHandler.FileName[0] = FILE_Erased;
if(WHandler.BaseFatEntry != 0)
{
u16Temporal=WHandler.BaseFatEntry;
do
{
WHandler.CurrentFatEntry=WHandler.BaseFatEntry;
WHandler.BaseFatEntry=FAT_Entry(WHandler.CurrentFatEntry,0,NEXT_ENTRY);
u32Sector=WHandler.CurrentFatEntry/(u16FAT_Sector_Size>>1);
u16Offset=WHandler.CurrentFatEntry%(u16FAT_Sector_Size>>1);
GetPhysicalBlock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer);
pu16FATPointer=(UINT16*)ag8FATReadBuffer;
pu16FATPointer+=u16Offset;
*pu16FATPointer=0x0000; // clear FAT entry
StorePhysicalBLock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer)
}while(WHandler.BaseFatEntry!=0xFFFF);
WHandler.BaseFatEntry=u16Temporal;
u32Sector=WHandler.CurrentFatEntry/(u16FAT_Sector_Size>>1);
u16Offset=WHandler.CurrentFatEntry%(u16FAT_Sector_Size>>1);
GetPhysicalBlock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer);
pu16FATPointer=(UINT16*)ag8FATReadBuffer;
pu16FATPointer+=u16Offset;
*pu16FATPointer=0x0000; // clear FAT entry
StorePhysicalBLock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer)
}
/* u32Sector=WHandler.BaseFatEntry/(u16FAT_Sector_Size>>1);
u16Offset=WHandler.BaseFatEntry%(u16FAT_Sector_Size>>1);
GetPhysicalBlock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer);
pu16FATPointer=(UINT16*)ag8FATReadBuffer;
pu16FATPointer+=u16Offset;
*pu16FATPointer=0x0000; // clear FAT entry
StorePhysicalBLock(u16FAT_FAT_BASE+u32Sector,ag8FATReadBuffer)
*/
//WHandler.BaseFatEntry = FILE_Index_Clear;
//WHandler.CurrentFatEntry = FILE_Index_Clear;
//WHandler.ClusterIndex = FILE_Index_Clear;
}
/* If Overwrite Function */
else if (u8Function==OVERWRITE)
{
pu8Pointer=WHandler.FileName;
for(u8Counter=0;u8Counter<11;u8Counter++)
*pu8Pointer++=u8FileName[u8Counter];
WHandler.Dir_Entry=(u16Block*EntriesPerBlock)+((u16Index)/RootEntrySize);
WHandler.File_Size=LWordSwap(sFileStructure->SizeofFile);
WHandler.BaseFatEntry=ByteSwap(sFileStructure->ClusterNumber);
if(WHandler.BaseFatEntry != 0)
{
u16Temporal=WHandler.BaseFatEntry;
do
{
WHandler.CurrentFatEntry=WHandler.BaseFatEntry;
WHandler.BaseFatEntry=FAT_Entry(WHandler.CurrentFatEntry,0,NEXT_ENTRY);
}while(WHandler.BaseFatEntry!=0xFFFF);
WHandler.BaseFatEntry=u16Temporal;
}
else
{
WHandler.BaseFatEntry=FAT_SearchAvailableFAT(0);
WHandler.CurrentFatEntry=WHandler.BaseFatEntry;
}
/*****************/
/* Double Check */
/*****************/
u8Counter=0;
u8ErrorCode=u16FAT_Cluster_Size;
while(u8ErrorCode != 0x01)
{
u8Counter++;
u8ErrorCode=u8ErrorCode>>1;
}
u16Temporal=(UINT16)WHandler.File_Size % (u16FAT_Sector_Size<<u8Counter);
WHandler.ClusterIndex= u16Temporal/u16FAT_Sector_Size;
WHandler.SectorIndex= 0;//u16Temporal%u16FAT_Sector_Size;
u8ErrorCode=FILE_FOUND;
}
/* If Modify Function */
else
{
pu8Pointer=WHandler.FileName;
for(u8Counter=0;u8Counter<11;u8Counter++)
*pu8Pointer++=u8FileName[u8Counter];
WHandler.Dir_Entry=(u16Block*EntriesPerBlock)+((u16Index)/RootEntrySize);
WHandler.File_Size=LWordSwap(sFileStructure->SizeofFile);
WHandler.BaseFatEntry=ByteSwap(sFileStructure->ClusterNumber);
if(WHandler.BaseFatEntry != 0)
{
u16Temporal=WHandler.BaseFatEntry;
do
{
WHandler.CurrentFatEntry=WHandler.BaseFatEntry;
WHandler.BaseFatEntry=FAT_Entry(WHandler.CurrentFatEntry,0,NEXT_ENTRY);
}while(WHandler.BaseFatEntry!=0xFFFF);
WHandler.BaseFatEntry=u16Temporal;
}
else
{
WHandler.BaseFatEntry=FAT_SearchAvailableFAT(0);
WHandler.CurrentFatEntry=WHandler.BaseFatEntry;
}
/*****************/
/* Double Check */
/*****************/
u8Counter=0;
u8ErrorCode=u16FAT_Cluster_Size;
while(u8ErrorCode != 0x01)
{
u8Counter++;
u8ErrorCode=u8ErrorCode>>1;
}
u16Temporal=(UINT16)WHandler.File_Size % (u16FAT_Sector_Size<<u8Counter);
WHandler.ClusterIndex= u16Temporal/u16FAT_Sector_Size;
WHandler.SectorIndex= u16Temporal%u16FAT_Sector_Size;
u8ErrorCode=FILE_FOUND;
}
}
}
}
/* If Write function */
if(u8Function==CREATE)
{
if(sFileStructure->FileName[0]==FILE_Clear || sFileStructure->FileName[0]==FILE_Erased)
{
pu8Pointer=WHandler.FileName;
for(u8Counter=0;u8Counter<11;u8Counter++)
*pu8Pointer++=u8FileName[u8Counter];
WHandler.Dir_Entry=(u16Block*EntriesPerBlock)+((u16Index)/RootEntrySize);
WHandler.File_Size=0;
WHandler.BaseFatEntry=FAT_SearchAvailableFAT(0);
WHandler.CurrentFatEntry=WHandler.BaseFatEntry;
WHandler.ClusterIndex=0;
WHandler.SectorIndex=0;
if(WHandler.BaseFatEntry)
u8ErrorCode=FILE_CREATE_OK;
else
u8ErrorCode=NO_FAT_ENTRY_AVAIlABLE;
}
}
sFileStructure++;
u16Index+=RootEntrySize;
}
u16Block++;
}
if(u16BlockNum==u16Block)
u8ErrorCode=NO_FILE_ENTRY_AVAILABLE;
return(u8ErrorCode);
}
/**************************CODIGO FAT.H*************************************************************
#ifndef __Fat__
#define __Fat__
/* Includes */
#include "FslTypes.h"
/************************* HIL ****************************/
/**********************************************************/
/* Includes */
#include "SD.h" // SD Card Driver
/* Storage HIL */
#define GetPhysicalBlock(A,B) (void)SD_Read_Block(A,B);
#define StorePhysicalBLock(A,B) (void)SD_Write_Block(A,B);
/**********************************************************/
/**********************************************************/
/* Macros */
#define ByteSwap(A) (A=(A<<

+(A>>

)
/* definitions */
#define MASTER_BLOCK 0x00
#define RootEntrySize 32
#define EntriesPerBlock 16 //Block size / RootEntrySize
#define RHandler_FAT_ENTRIES 8
/*-- Directory Defines --*/
#define FILE_AVAILABLE 0x00
#define FILE_USER 0xFF
#define FILE_Erased 0xE5
#define FILE_Clear 0x00
#define AT_VOLUME 0x01
#define AT_DIRECTORY 0x02
#define AT_HIDDEN 0x04
#define AT_SYSTEM 0x08
#define AT_READONLY 0x10
#define AT_ARCHIVE 0x20
#define FILE_Index_Clear 0x0000
enum
{
READ,
CREATE,
MODIFY,
DELETE,
NEXT_ENTRY,
WRITE_ENTRY,
OVERWRITE
};
enum
{
FILE_FOUND,
FILE_NOT_FOUND,
FILE_CREATE_OK,
NO_FILE_ENTRY_AVAILABLE,
NO_FAT_ENTRY_AVAIlABLE,
ERROR_IDLE
};
/* typedef */
typedef struct _ReadHandler
{
UINT16 FAT_Entry;
UINT16 SectorOffset;
UINT16 Dir_Entry;
UINT32 File_Size;
}ReadRHandler;
typedef struct _WriteRHandler
{
UINT8 FileName[8];
UINT8 Extension[3];
UINT16 Dir_Entry;
UINT32 File_Size;
UINT16 BaseFatEntry;
UINT16 CurrentFatEntry;
UINT16 SectorIndex;
UINT16 ClusterIndex;
}WriteRHandler;
/* Root Directory Structure */
typedef struct _root_Entries
{
UINT8 FileName[8];
UINT8 Extension[3];
UINT8 Attributes;
UINT8 _Case;
UINT8 MiliSeconds;
UINT16 CreationTime;
UINT16 CreationDate;
UINT16 AccessDate;
UINT16 Reserved;
UINT16 ModificationTime;
UINT16 ModificationDate;
UINT16 ClusterNumber;
UINT32 SizeofFile;
}root_Entries;
/* Master Boot Record */
typedef struct _MasterBoot_Entries
{
UINT8 JMP_NOP[3];
UINT8 OEMName[8];
UINT16 BytesPerSector;
UINT8 SectorsPerCluster;
UINT16 ReservedSectors;
UINT8 FatCopies;
UINT16 RootDirectoryEntries;
UINT16 SectorsLess32MB;
UINT8 MediaDescriptor;
UINT16 SectorsPerFat;
UINT16 SectorsPerTrack;
UINT16 NumberOfHeads;
UINT32 HiddenSectors;
UINT32 SectorsInPartition;
UINT16 LogicalNumberOfPartitions;
UINT8 ExtendedSignature;
UINT32 SerialNumber;
UINT8 VolumeNumber[11];
UINT8 FatName[8];
UINT8 ExcecutableCode[448];
UINT8 ExcecutableMarker[2];
}MasterBoot_Entries;
/*
void FAT_CreateFATLinks(UINT16);
void FAT_LS(void);
*/
/* Prototypes */
UINT32 LWordSwap(UINT32);
void FAT_FileClose(void);
void FAT_Read_Master_Block(void);
UINT8 FAT_FileOpen(UINT8*,UINT8);
void FAT_FileWrite(UINT8*,UINT32);
UINT16 FAT_FileRead(UINT8*);
UINT16 FAT_Entry(UINT16,UINT16,UINT8);
UINT16 FAT_SearchAvailableFAT(UINT16);
#endif /* __Fat__ */
/**************************CODIGO SD.C*************************************************************
/* Includes */
#include "SD.h"
T32_8 gu8SD_Argument;
/*****************************************************************************/
UINT8 SD_Init(void)
{
_SD_PRESENT=_IN;
/* Check for SD */
if(SD_PRESENT)
return(NO_SD_CARD);
/* Initialize SPI Module */
InitSPI();
/* Start SD card Init */
SPI_SS=ENABLE;
SD_CLKDelay(10); // Send 80 clocks
SPI_SS=DISABLE;
gu8SD_Argument.lword=0;
SD_CLKDelay(

;
/* IDLE Command */
SPI_SS=ENABLE;
if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE))
{
SPI_SS=DISABLE;
return(INIT_FAILS);
}
SPI_SS=DISABLE;
(void)ReadSPIByte(); // Dummy SPI cycle
/* Initialize SD Command */
SPI_SS=ENABLE;
while(SD_SendCommand(SD_CMD1|0x40,SD_OK));
SPI_SS=DISABLE;
(void)ReadSPIByte(); // Dummy SPI cycle
/* Block Length */
SPI_SS=ENABLE;
gu8SD_Argument.lword=SD_BLOCK_SIZE;
if(SD_SendCommand(SD_CMD16|0x40,SD_OK))
{
SPI_SS=DISABLE;
return(INIT_FAILS);
}
SPI_SS=DISABLE;
HighSpeedSPI();
WriteSPIByte(0x00);
WriteSPIByte(0x00);
return(OK);
}
/*****************************************************************************/
UINT8 SD_Write_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer)
{
UINT16 u16Counter;
SPI_SS=ENABLE;
gu8SD_Argument.lword=u16SD_Block;
gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;
if(SD_SendCommand(SD_CMD24|0x40,SD_OK))
{
SPI_SS=DISABLE;
return(WRITE_COMMAND_FAILS);
}
WriteSPIByte(0xFE);
for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
WriteSPIByte(*pu8DataPointer++);
WriteSPIByte(0xFF); // checksum Bytes not needed
WriteSPIByte(0xFF);
for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++);
if((ReadSPIByte() & 0x0F) != 0x05)
{
SPI_SS=DISABLE;
return(WRITE_DATA_FAILS);
}
while(SPI_Receive_byte()==0x00); // Dummy SPI cycle
SPI_SS=DISABLE;
return(OK);
}
/*****************************************************************************/
UINT8 SD_Read_Block(UINT32 u16SD_Block,UINT8 *pu8DataPointer)
{
UINT8 u8Temp=0;
UINT16 u16Counter;
SPI_SS=ENABLE;
gu8SD_Argument.lword=u16SD_Block;
gu8SD_Argument.lword=gu8SD_Argument.lword<< SD_BLOCK_SHIFT;
if(SD_SendCommand(SD_CMD17|0x40,SD_OK))
{
SPI_SS=DISABLE;
return(READ_COMMAND_FAILS);
}
while(u8Temp!=0xFE)
u8Temp=SPI_Receive_byte();
for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)
*pu8DataPointer++=SPI_Receive_byte();
(void)ReadSPIByte(); // Dummy SPI cycle
(void)ReadSPIByte();
SPI_SS=DISABLE;
(void)ReadSPIByte(); // Dummy SPI cycle
return(OK);
}
/*****************************************************************************/
UINT8 SD_SendCommand(UINT8 u8SDCommand,UINT8 u8SDResponse)
{
UINT8 u8Counter;
volatile UINT8 u8Temp=0;
/* Send Start byte */
WriteSPIByte(u8SDCommand);
/* Send Argument */
for(u8Counter=0;u8Counter<4;u8Counter++)
WriteSPIByte(gu8SD_Argument.bytes[u8Counter]);
/* Send CRC */
WriteSPIByte(0x95);
/* Response RHandler */
u8Counter=SD_WAIT_CYCLES;
do
{
u8Temp=ReadSPIByte();
u8Counter--;
}while((u8Temp != u8SDResponse) && u8Counter > 0);
if(u8Counter) return(OK);
else return(COMMAND_FAILS);
}
/*****************************************************************************/
void SD_CLKDelay(UINT8 u8Frames)
{
while(u8Frames--)
WriteSPIByte(0xFF);
}
/**************************CODIGO SD.H*************************************************************
#ifndef __SD__
#define __SD__
/* Includes */
#include "FslTypes.h"
/************************* HIL ****************************/
/**********************************************************/
/* Includes */
#include "SPI.h" // SPI Driver
/* HIL */
#define InitSPI SPI_Init
#define ReadSPIByte SPI_Receive_byte
#define WriteSPIByte SPI_Send_byte
#define HighSpeedSPI SPI_High_rate
/**********************************************************/
/**********************************************************/
/* User definitions */
#define SD_BLOCK_512
#define SD_WAIT_CYCLES 10
/* SD card Inserted detection Pin */
#define SD_PRESENT PTBD_PTBD7
#define _SD_PRESENT PTBDD_PTBDD7
/* Error Codes */
enum
{
OK,
COMMAND_FAILS,
INIT_FAILS,
WRITE_COMMAND_FAILS,
WRITE_DATA_FAILS,
READ_COMMAND_FAILS,
READ_DATA_FAILS,
NO_SD_CARD
};
/* Status */
enum
{
SD_OK,
SD_IDLE
};
/* TypeDefs */
typedef union
{
UINT8 bytes[4];
UINT32 lword;
}T32_8;
/* Stardar Definitions */
#ifdef SD_BLOCK_512
#define SD_BLOCK_SIZE (0x00000200)
#define SD_BLOCK_SHIFT (9)
#define BLOCK_SIZE 512
#endif
/* Static Definitions */
/******************************* SD Card Standard Commands **********************************/
enum{
SD_CMD0, /* Resets the SD Memory Card */
SD_CMD1, /* Sends host capacity support information and activates the card's
initialization process. HCS is effective when card receives SEND_IF_COND
command. Reserved bits shall be set to '0'. */
SD_CMD2,
SD_CMD3,
SD_CMD4,
SD_CMD5,
SD_CMD6, /* Checks switchable function (mode 0) and switches card function (mode 1).*/
SD_CMD7,
SD_CMD8, /* Sends SD Memory Card interface condition that includes host supply voltage
information and asks the accessed card whether card can operate in supplied
voltage range. Reserved bits shall be set to '0'.*/
SD_CMD9, /* Asks the selected card to send its cardspecific data (CSD)*/
SD_CMD10, /* Asks the selected card to send its card identification (CID) */
SD_CMD11,
SD_CMD12, /* Forces the card to stop transmission in Multiple Block Read Operation */
SD_CMD13, /* Asks the selected card to send its status register. */
SD_CMD14,
SD_CMD15,
SD_CMD16, /* Sets a block length (in bytes) for all following block commands (read and
write) of a Standard Capacity Card. Block length of the read and write
commands are fixed to 512 bytes in a High Capacity Card. The length of
LOCK_UNLOCK command is set by this command in both capacity cards.*/
SD_CMD17, /* Reads a block of the size selected by the SET_BLOCKLEN command.*/
SD_CMD18, /* Continuously transfers data blocks from card to host until interrupted by a
STOP_TRANSMISSION command.*/
SD_CMD19,
SD_CMD20,
SD_CMD21,
SD_CMD22,
SD_CMD23,
SD_CMD24, /* Writes a block of the size selected by the SET_BLOCKLEN command. */
SD_CMD25, /* Continuously writes blocks of data until ’Stop Tran’ token is sent
(instead ’Start Block’).*/
SD_CMD26,
SD_CMD27, /* Programming of the programmable bits of the CSD. */
SD_CMD28, /* If the card has write protection features, this command sets the write protection bit
of the addressed group. The properties of write protection are coded in the card
specific data (WP_GRP_SIZE). The High Capacity Card does not support this command.*/
SD_CMD29, /* If the card has write protection features, this command clears the write protection
bit of the addressed group. The High Capacity Card does not support this command. */
SD_CMD30, /* If the card has write protection features, this command asks the card to send the
status of the write protection bits.6 The High Capacity Card does not support this command. */
SD_CMD31,
SD_CMD32, /* Sets the address of the first write block to be erased.*/
SD_CMD33, /* Sets the address of the last write block of the continuous range to be erased. */
SD_CMD34,
SD_CMD35,
SD_CMD36,
SD_CMD37,
SD_CMD38, /* Erases all previously selected write blocks */
SD_CMD39,
SD_CMD40,
SD_CMD41,
SD_CMD42, /* Used to Set/Reset the Password or lock/unlock the card. A transferred data block includes
all the command details - refer to Chapter 4.3.7. The size of the Data Block is defined
with SET_BLOCK_LEN command. Reserved bits in the argument and in Lock Card Data Structure
shall be set to 0. */
SD_CMD43,
SD_CMD44,
SD_CMD45,
SD_CMD46,
SD_CMD47,
SD_CMD48,
SD_CMD49,
SD_CMD50,
SD_CMD51,
SD_CMD52,
SD_CMD53,
SD_CMD54,
SD_CMD55, /* Defines to the card that the next command is an application specific command
rather than a standard command */
SD_CMD56, /* Used either to transfer a Data Block to the card or to get a Data Block from the card
for general purpose/application specific commands. In case of Standard Capacity SD
Memory Card, the size of the Data Block shall be defined with SET_BLOCK_LEN command.
Block length of this command is fixed to 512-byte in High Capacity Card. */
SD_CMD57,
SD_CMD58, /* Reads the OCR register of a card. CCS bit is assigned to OCR[30]. */
SD_CMD59, /* Turns the CRC option on or off. A ‘1’ in the CRC option bit will turn the option on,
a ‘0’ will turn it off */
SD_CMD60,
SD_CMD61,
SD_CMD62,
SD_CMD63
};
/* Prototypes */
UINT8 SD_Init(void);
UINT8 SD_SendCommand(UINT8,UINT8);
void SD_CLKDelay(UINT8);
UINT8 SD_Write_Block(UINT32,UINT8*);
UINT8 SD_Read_Block(UINT32,UINT8*);
#endif /* __SD__ */
/**************************CODIGO SPI.C*************************************************************
#include "SPI.h"
/************************************************/
void SPI_Init(void)
{
//SOPT2 = SOPT2_SPI1PS_MASK; // Drive PTE as SPI port
SPI_SS = 1;
_SPI_SS= 1;
SPI2BR = 0x24; // 375 Khz
SPI2C2 = 0x00;
SPI2C1 = SPI2C1_SPE_MASK | SPI2C1_MSTR_MASK;
}
/************************************************/
void SPI_Send_byte(UINT8 u8Data)
{
(void)SPI2S;
SPI2DL=u8Data;
while(!SPI2S_SPTEF);
}
/************************************************/
UINT8 SPI_Receive_byte(void)
{
(void)SPI2DL;
SPI2DL=0xFF;
while(!SPI2S_SPRF);
return(SPI2DL);
}
/************************************************/
void SPI_High_rate(void)
{
SPI2C1 = 0x00;
SPI2BR = 0x11; // 375 Khz
SPI2C1 = SPI2C1_SPE_MASK | SPI2C1_MSTR_MASK;
}
/************************SPI.H**********************************************
#ifndef __SPI__
#define __SPI__
/* Includes */
#include "FslTypes.h"
#include "derivative.h"
/* definitions */
#define SPI_SS PTBD_PTBD3 /* Slave Select */
#define _SPI_SS PTBDD_PTBDD3
//#define SPI_SS PTBD_PTBD5 /* Slave Select */
//#define _SPI_SS PTBDD_PTBDD5
#define ENABLE 0
#define DISABLE 1
/* Global Variables */
/* Prototypes */
void SPI_Init(void);
void SPI_Send_byte(UINT8 u8Data);
UINT8 SPI_Receive_byte(void);
void SPI_High_rate(void);
#endif /* __SPI__ */
/***********************************MAIN*****************************************
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "FslTypes.h" /* Freescale Types */
#include "SD.h" /* SD Driver */
#include "FAT.h" /* FAT Driver */
#include "Config.h"
UINT8 mens[]={"HELLO WORLD"};
UINT8 flag =0;
void MCU_Init(void);
void main(void) {
volatile UINT8 u8Error;
u8Error=153;
MCU_Init();
SPI_Init();
EnableInterrupts; /* enable interrupts */
/* include your code here */
u8Error=SD_Init();
FAT_Read_Master_Block();
// Creating the file if it doesn't exist
if (FAT_FileOpen(FILE_NAME, MODIFY) == FILE_NOT_FOUND)
{
u8Error=FAT_FileOpen("LOG.TXT",CREATE);
}
FAT_FileClose();
for(;

{
if (flag == 0){
flag=1;
u8Error=FAT_FileOpen("LOG.TXT",MODIFY);
FAT_FileWrite(mens,11);
FAT_FileClose();
}
}
}