Autor Tema: Duda Libreria FAT Freescale  (Leído 3795 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado hermesericelrojo

  • PIC10
  • *
  • Mensajes: 16
Duda Libreria FAT Freescale
« en: 24 de Abril de 2012, 15:16:26 »
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<8)
                *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<<8)+(A>>8))

/* 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(8);  
    
    /* 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();
    
     }
  


  }
  
}





« Última modificación: 24 de Abril de 2012, 15:18:47 por hermesericelrojo »

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Duda Libreria FAT Freescale
« Respuesta #1 en: 24 de Abril de 2012, 18:00:19 »
Hola, tal vez podrías ver con esta:

http://sourceforge.net/projects/microfs/

Saludos !

Desconectado hermesericelrojo

  • PIC10
  • *
  • Mensajes: 16
Re: Duda Libreria FAT Freescale
« Respuesta #2 en: 24 de Abril de 2012, 21:25:08 »
Gracia RICHI777.
Mirando el archivo que adjuntante, encontre que se parece a un driver de    
MicroLogger [MC9S08SH32 y MMC/SD Card ] [Post 1 ]que publicaste en el foro, quisiera saber si es posible adaptarlo al  MC JM60 de Freescale, y si es posible
leer archivos de la SD como imagenes .JPG para ser enviadas por serial.
Saludos!

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Duda Libreria FAT Freescale
« Respuesta #3 en: 25 de Abril de 2012, 10:07:48 »
Hola, es posible, solo tenes que adaptar las funciones bajo nivel de acceso al hardware. Como están en los post los probé en un MC SH32 y en un ColdFire V1. Una vez que funcione podes escribir y leer cualquier archivo. El concepto es minimalista, es decir solamente tiene las funciones básicas (crear, abrir, leer y escribir)
Si necesitas file system con más funcionalidad tendrias que optar por el que hizo Suky ( un maestro de maestros en este foro ) o el que hizo Chang. Te paso algunos links.

http://elm-chan.org/fsw/ff/00index_e.html

http://sistemasembebidos.com.ar/foro/index.php?topic=456.0

Saludos !