Implementing Freescale FAT Lite on ColdFire

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Implementing Freescale FAT Lite on ColdFire

5,000 Views
PabloA
Contributor II

Hi there, I need some help about this issue:

 

I'm working in a data logger project like DEMOFLEXISJMSD_DataLogger_V2

http://www.freescale.com/webapp/sps/site/training_information.jsp?code=WBNR_SDCARDREADER_S08JM&fsrch...

This example use a SD card and Freescale FAT Lite to storage data.

 

I implemented the same FAT functions in the MCF51CN128RM ColdFire with the following results:

 

1. SD_Init() function returns:

     Ok (0).

 

2. FAT_FileOpen (FILE_NAME, MODIFY) function returns:

    FILE_NOT_FOUND (1) ->     If the file was not created with the same function with CREATE (1) as parameter.

                                              If I create a file using Windows XP, this function doesn't found it.

 

     FILE_FOUND (0) ->             Just if the file was created using FAT_FileOpen function.

 

3. FAT_FileOpen (FILE_NAME, CREATE) function returns:

     FILE_CREATE_OK (2) ->  But when I read the SD Card using Windows XP nothing appears.

 

I'm using FAT functions like this:

 

 

SD_Card_Status = SD_Init();

 

if (SD_Card_Status != OK)

{

     return;

}

 

FAT_Read_Master_Block();

 

SD_Card_Status = FAT_FileOpen (FILE_NAME, MODIFY);

 

if (SD_Card_Status = FILE_NOT_FOUND)

{

     SD_Card_Status = FAT_FileOpen (FILE_NAME, CREATE);

}

FAT_FileClose();

 

 

SD_Card_Status = FAT_FileOpen (FILE_NAME, MODIFY);

FAT_FileWrite (SD_String_Array, 20);

FAT_FileClose();

 

In this forum I found a discussion about Freescale FAT (https://community.freescale.com/message/86766#86766) but i can't solve the problem.

Even I  tried changing some part of the code suggested in the forum, but it doesn't work.

 

Cuestions:

 

Why FAT_FileOpen function returns FILE_CREATE_OK and Windows can't read it?

Why FAT FileOpen function can't recognize a file created with Windows?

Is this FAT library able to manage up to 2Gbs?

 

If some body test Freescale FAT Lite at ColdFire, please give me some tips.

 

Best regards!

 

Pablo Suárez

Labels (1)
0 Kudos
35 Replies

2,123 Views
guille
Contributor II

Hi there, I just published a revised version of FAT Lite. Some improvements were taken from this thread (Re: Problems porting SD FAT to MCF51 JM Badge Board - Datalogger application),  the others were the result of the efforts of me and my team.

http://code.google.com/p/sdfatlite/

Cheers!

0 Kudos

2,123 Views
carlospalma
Contributor I

This might seem a noob's question, but why on earth are there three main modules on the example you provided?, that is mainFAT, mainSD and mainSPI all have an infinite loop. I had never seen that before.

0 Kudos

2,123 Views
guille
Contributor II

Oh I Will correct that and upload it again. Those are the main functions were I tested the different modules independently. mainFat.c is the main that you need, thx for your comment.

0 Kudos

2,123 Views
carlospalma
Contributor I

I have been working with the modified library you provided, but for some reason when I try to read the file LOG1.txt using my computer it shows nothing...that is even after I confirmed the routine to create a file was accessed by setting an LED on. Could you point me in the right direction? Is the format I'm using for my card the right one, because I have formatted it using windows seven and choosing FAT(default) .

0 Kudos

2,123 Views
guille
Contributor II

You should use some tool that gives you raw access to the file system, like WinHex, to verify the data is correctly write into the FS on the SD card, before trying with Windows. I read the structures described here (http://www.maverick-os.dk/FileSystemFormats/FAT16_FileSystem.html) to understand and improve the Fat Lite library provided by Freescale.

There are many posible cases and i don't probe them all. The idea is to keep the library as simple as posible.

FAT (Default) is correct, it's FAT16 (you can see this with WinHex). It is posible that, for some reason, the library is not correctly writing the new file entry in the Root Directory section of the FS.

Please let me know about your progress after using WinHex and reading the FAT structures!

Guille

0 Kudos

2,123 Views
carlospalma
Contributor I

Hi Guille. Listen, so far I got it to work modifying an already created file, I have to warn you and the community that even if winhex shows the boot information on block 0, it is not there, I used the method proposed by the original guy who uploaded the library (a loop to find boot information), and when reading main_offset using Freemaster (great tool by the way), it showed 226 as the block in which the boot information is stored. I don't know if it's because of the SD card I'm using, but changing that and this line of code :

while(ag8FATReadBuffer[0]!= 0xEB || ag8FATReadBuffer[1]!=0x3C || ag8FATReadBuffer[2]!=0x90)

did the trick for me.

Cheers!

the line of code used to read like this:

while(ag8FATReadBuffer[0]!=0xEB && ag8FATReadBuffer[0]!=0x3C && ag8FATReadBuffer[0]!=0x90)

I did this because negating an AND sentence gives an OR sentence (boolean logic)

0 Kudos

2,123 Views
jatinarora
Contributor I

I am working with the same library on MPC5604B 32 bit uC, the problem i am facing is that the routine to create the file is not being accessed. My debugger shows both u16Block and  u16BlockNum in UINT8 FAT_FileOpen(UINT8* pu8FileName,UINT8 u8Function) as 0. Due to this while(u16Block < u16BlockNum && u8ErrorCode==ERROR_IDLE) is not executed.

and thus, the file create routine is not run. Please help me with this..


0 Kudos

2,123 Views
TomE
Specialist II

Are you sure you've fixed the byte packing problems mentioned in this thread and in the one referenced from this thread?

Re: Problems porting SD FAT to MCF51 JM Badge Board - Datalogger application

Make sure you're calling any required initialization code. Also that you're checking all functions that return error codes and doing something with them (like printing an error message).

Tom

0 Kudos

2,123 Views
jatinarora
Contributor I

I am using guille's library which i suppose is bug free. I have taken care of all the initializations. The problem is that     UINT8 FAT_FileOpen(UINT8* pu8FileName,UINT8 u8Function)     function is returning NO_FAT_ENTRY_AVAIlABLE, because u16Block =  u16BlockNum, this is the reason why no file is being created. Also note the the SD initialize program is working fine.


this is my main program :


int main(void) {

volatile int i = 0;

uint8_t k=0;

uint8_t m=0;

initModesAndClock();

initPeriClkGen();

disableWatchdog(); 

SPI_Init();

config_SIUL();

k=SD_Init();

if(k==1)

{

SIU.PGPDO[2].R &= 0x0b000000;  // to glow an led and the led does glow.

}

    FAT_Read_Master_Block(); 

   

    if (FAT_FileOpen("FILE3.TXT",MODIFY) == FILE_NOT_FOUND)

    {

      m=FAT_FileOpen("FILE3.TXT",CREATE);

    }       

    FAT_FileClose();

    

while(1) {}

}

0 Kudos

2,123 Views
jatinarora
Contributor I

i analyzed it more,

at this line of code (fat.c...read master block)                               if(PartitionTable->MBRSignature!=0x55AA) return;

the value of PartitionTable->MBRSignature is 0x0000 and not 0x55AA, thus it is not completing the read master block program. thats why u16Block =  u16BlockNum..

0 Kudos

2,123 Views
jatinarora
Contributor I

also when i use default freescale fat library (without changing it) from datalogger project, i am stuck at

while(ag8FATReadBuffer[0]!= 0xEB && ag8FATReadBuffer[1]!=0x3C && ag8FATReadBuffer[2]!=0x90)                 //problem is that it is not leaving this loop.

    {

        GetPhysicalBlock(u16Main_Offset++,&ag8FATReadBuffer[0]);  //thus it goes on doing this.

    }

it never exists the loop....

ARE  THESE 2 PROBLEMS RELATED, COZ IN BOTH CASES I AM STUCK IN READ MASTER BLOCK ROUTINE.

Please help.

0 Kudos

2,123 Views
TomE
Specialist II

> I am using guille's library which i suppose is bug free.


No other code on the planet is, so assume that?

> i am stuck at

So put a breakpoint in that function and examine the DATA that you're reading in. What is in ag8FATReadBuffer[] that isn't 0x903CEB? It is perfectly clear what the code is expecting, so see what it is reading.

What FUNCTION is it in? Telling us the name of the function would probably tell us what it is looking for.

Why don't you list all the other things you've checked (like the byte packing) so we know you're following our advice?

Google finds "eb 3c 90" here:

http://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html

They're the first three bytes of the boot sector, but they don't have to be those values:

http://en.wikipedia.org/wiki/FAT_file_system#Boot_Sector

If the code is ONLY matching on those values, then that may be your problem (or the problem with that code). It may only read IBM PC floppy disks from 1984, or those ones that still copy it exactly.

I've just put a random USB stick in my computer and checked the first block:

0000000 eb 58 90 4d 53 44 4f 53 35 2e 30 00 02 08 26 00

0000020 02 00 00 00 00 f8 00 00 3f 00 ff 00 26 00 00 00

That is a legal boot sector, but the code you posted would not recognise it as it only checks for one common set of values, and not all the possible legal values. It that a bug or was it only written to work with a limited range of media?

Tom

0 Kudos

2,123 Views
jatinarora
Contributor I

I think that struct alignment is the problem i am facing.

can anyone guide me how to change struct alignment on codewarrior for power pc and does power pc actually allow the same.


I tried to do it and in struct alignment option of EPPC processor setting in flash settings i get 3 options

a. 64K

b. 64K 4 byte

c. Power pc... when i used anything other than option c, all my peripherals like SIUL and DSPI stop working.

2. The thread also talks about endian support, my uC originally works on Big endian, when i try to change it to little endian in EPPC target settings in flash settings, I recieve an error "cannot mix little and big endian".

0 Kudos

2,123 Views
TomE
Specialist II

> can anyone guide me how to change struct alignment on codewarrior for power pc


In a ColdFire Hardware forum? You should search more appropriate forums for the answer to that question.


From my memory there's plenty of information already in this thread that should give you hints about how to configure CW. The CW Documentation should have this in it too.

Tom

0 Kudos

2,123 Views
guille
Contributor II

Hi Carlos, you are right about replacing && with ||, i will correct it and update the repo soon. That line was commented on the library, so it shouldn't do any harm. However, regarding the method to obtain the location of the MBR (of the first partition), to further obtain the location of the Root Directory, to further access the file you want, you have two options:

1. The method that the library originally use, commented in our version of the library: 

while(ag8FATReadBuffer[0]!=0xEB && ag8FATReadBuffer[0]!=0x3C && ag8FATReadBuffer[0]!=0x90)

        GetPhysicalBlock(u16Main_Offset++,&ag8FATReadBuffer[0]); 

        __RESET_WATCHDOG();

}

u16Main_Offset--; //Offset correction

2.  Our method:

GetPhysicalBlock(0,&ag8FATReadBuffer[0]); //Get physical block zero from the SD

PartitionTable=(PartitionTable_Entries*)ag8FATReadBuffer; //Load the content of the buffer into the apropiate structure

if(PartitionTable->MBRSignature!=0x55AA) return; // Verify MBR Signature

u16Main_Offset=(UINT16)LWordSwap(PartitionTable->Partition[0].LBAStart);  //Compute address of first partition

GetPhysicalBlock(u16Main_Offset,&ag8FATReadBuffer[0]);  //Get physical block where the first partition is

if(ag8FATReadBuffer[0]!= 0xEB || ag8FATReadBuffer[1]!=0x3C || ag8FATReadBuffer[2]!=0x90) return;  // Verify the first partition start pattern

As you can see, our method doesn't need to iterate in order to obtain the location of the first partition. It just get it from the values loaded in the MBR (not the MBR of the first partition -offset=226-, but the MBR of the physical volume, always located in zero address). As you said, i asume that the boot info of the physical volume is in block zero. I read this from the FAT specs. The boot info of the first partition is not in block zero. In your case, is in block 226. It's a little messy, in my case, the first partition began at 239.

I follow this picture to write the _PartitionTable_Entries structure

Tabla de particiones - Wikipedia, la enciclopedia libre

Same here

Maverick - The Operating System

PD: Sorry for my english!

0 Kudos

2,123 Views
sebasira
Senior Contributor I

Thank you Guille!!

I'll give it a try and let you know about my experience

Cheers!

SebaS

0 Kudos

2,123 Views
guille
Contributor II

Thx, good luck!

0 Kudos

2,123 Views
sebasira
Senior Contributor I

Hi guille!

I didn't have time to test your library before, and I started yesterday. Luckly for me, when I visit the site to download it, I found out that you already have a newer version.

I must tell you, I've got a custom hardware which has and SD socket, and it's attached to a MCF51QE128. It's working pretty good with suan's library I've posted before, but I've notice a problem whenever file size exceeded 3.5MB (don't know why yet). This problem encourage me to test yours and maybe replace the firmware with it.

But I think I've found some strange things that I want to point out: (please correct me if I'm wrong, what I'm telling is based on my experience)

1) First I thought that the way to handle SD cards via SPI was to initialize it at a slow speed (375kHz or 400kHz), and then must boost to a higher one, above 4MHz. But I've notice that in SD.c the call HighSpeedSPI() was commented. Is that ok?

2) Assuming that we must work at a higher speed, then the BaudRate divider inside SPI_High_rate is not correct, if your bus clock is 24MHz. Also, if you actually are running at 24MHz (I'm also at that speed) then the low speed is wrong, because if you want 375kHz you need to divide 24MHz by 64, wich means SCI2BR = 0x05 (0b00000101) instead of 0x06. (I need to change the value 0x06 for 0x05 otherwise SD card wouldn't be initilized at least for me)

3) in the SPI_Receive_byte shouldn't you wait for SPI2S_SPTEF before sending a dummy byte? And shouldn't you read STATUS register instead of DATA register before sending, in order to clear flags? I mean, replace taht routine with this one:

UINT8 SPI_Receive_byte(void){

     while(!SPI2S_SPTEF) ; 

     (void)SPI2S;

     SPI2DL=0xFF;

     while(!SPI2S_SPRF) ;

     return(SPI2DL);

}


I'd like to add that I've used the original freescale subroutines for a while (before suan's library) with this same hardware but sometimes it just get stuck on a SPI loop (if I recall correctly maybe the ReadMasterBlock loop) wich makes it impossible to use. Now with your new method maybe it's solved. I've manage to run this library with the changes above,but it still hangs here:

for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++)

        *pu8DataPointer++=SPI_Receive_byte();

inside SD_Read_Block

I'm also guessing that if we combine suan's library (wich IMHO is great) with your new method we can finally get a real working FAT for ColdFire

One last thing I just remember when writting "ColdFire".... For the original library, the struct alignment of the project MUST be changed to byte instead of coldfire(long). In your's that is also needed or not? I tried it both ways but I cannot go futher because of the problem above.

Thanks !!

Saludos (I'm also from Argentina, jeje)

SebaS

0 Kudos

2,123 Views
guille
Contributor II

Hi Seba, i really apreciate your dedication! I'm travelling right now, without computer! i'll come back to my job in may, and give you a full reply! Thx, sorry and good look!

0 Kudos

2,123 Views
sebasira
Senior Contributor I

Hello Guille! I'm looking forward your replay. For now, I'll dive into a new project and then when you come  back, I''l put my hands back onto this

Best Regards!

SebaS

0 Kudos