Creating a .txt file in AVR

Go To Last Post
227 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In mmc.c your power_on almost certainly has this:

static
void power_on (void)
{
	PORTE |= (1<<CARDPOWER);				/* Socket power ON */
	for (Timer1 = 3; Timer1; );	/* Wait for 30ms */
	PORTB = 0b10110101;			/* Enable drivers */
	DDRB  = 0b11000111;
	SPCR = 0b01010000;			/* Initialize SPI port (Mode 0) */
	SPSR = 0b00000001;
}

The value written to SPCR sets just SPE (to enable SPI) and MSTR (to operate in Master mode). As the SPR1/SPR0 bits are left at default (0) this will run the SPI as fast as it can go (F_CPU / 2 because bit 0 of SPSR (which is SPI2X) is also being set)

As for the file processing. Only you know what the data is and how you want to process so I'll leave it for you to work out how you want to process it but my point was simply that if it simply consists of 7 possible data fields (ABCDEFG) that are each of 8 bytes that you could just use ONE byte at the very start of the file to say in bit flags which of the data items were "active". So rather than removing all the D's with a costly processing of the file you actually just write ONE byte at the start to effectively say "ignore D". Later when you read the data you start by reading the control byte and for any bits that are 1 (ABCEFG) you read and process the data and for any that are 0 you just skip the data.

Sure this leaves "dead" data in the file but does it really matter? We're talking SD cards which are HUGE!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In regards to your bit flag, it will not work well for me, becuase i am updating a lookup table by removing unessary address. So the list could be in 100's.

Regards

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So put an "active/dead" flag on every one of the 100's of entries and when it's to be deleted simply re-write the state of the flag then, when later reading through the data ignore "dead" ones. You can also use this as a marker for the next slot to be used - when looking for a slot of new data just scan through for the first "dead" entry and re-use. It may also be possible to resurrect dead entries simply by flipping their flag back to "alive" again.

If you know the significance of the value 0xE5 in FAT (and CP/M!) filing systems you may recognise what I just described ;-)

(actually it works for resurrection in CP/M but in FAT switching the E5 may not be enough if the "first cluster" entry in the directory has been cleared)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

See what i am doing is trying to make the scanning of the Lookup table short as possible, so if i had flags with dead entires, my scan would still read it.

But a entry is removed once in a while, but scanning is down much more often.

What i do is that if a new entry needs to be saved, save it to the end of file, using flseek.

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But i guess your method would save me some RAM.

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's so demotivating...

i changed the Max_SS in ff.h to 1024, because with values above, the Mega32 doesn't work and formatted my Card with the same value, but i still get FR_NO_FILESYSTEM
this return value can be generated 2 times in the auto_mount-routine in ff.c

Do you have any ideas, what i could do furthermore?

Bytheway: i don't get a notification-email from avr-freaks on a new answer here. Do you have the same problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Add debug to the lowest level MMC sector read routine to dump each sector read as a hex dump of the entire 512 bytes and make sure the data being read by the AVR is the same as you see in WinHex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello

The nofilesystem-message comes from here:

if (fmt || LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* No valid FAT patition is found */
  return FR_NO_FILESYSTEM;

What is to do here?

I have an ISP-Programmer, but somehow my avr-Studio can't go in Debug-mode with it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I meant that if the AVR where you are running this code has a UART link to a PC then use printf()s via that to get a picture of what mmc.c and ff.c are "thinking" inside.

(Cliff using a different ID)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unfortunately i don't have a UART. I'm doing my debugging with a few LEDs.
So i can visualize Byte, letting one LED blink in a for-loop.

Perhaps i could send my code to you, that it can be verified, if the code is not working or sth. else. Is that possible?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sure but which model of AVR is it for?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For a Mega32.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh right, I may have one somewhere but if not I'll try it with mega16 as I definitiely have those. ZIP or RAR your project and then either attach it to a post here or to a PM (to "clawson" - not this account)

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I have an ISP-Programmer, but somehow my avr-Studio can't go in Debug-mode with it.

That's because an ISP-programmer simply isn't a debugger.

Quote:
Unfortunately i don't have a UART.

Quote:
a Mega32

The ATmega32 most certainly has a UART.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No. ;-) I mean, that i have no possibility, to use UART on my Computer. I just have USB-Ports, so i need an adapter for UART to USB, but i didn't really was behind looking for such a thing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does this expression stand for?(from ff.h)

#define	LD_WORD(ptr)		(WORD)(*(WORD*)(BYTE*)(ptr))

In the FAT-FS-User-Forum a user comes with this statement:

if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)
   return 2;

So he compares sth. at the end of the Bootsector, as i understood so far. Bur for a C-Beginnner, this looks a little cryptic. Please help me out.
Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's just being used to pick up a 16bit value from an 8bit array. He could have done it as:

if ((fs->win[BS_55AA] != 0x55) || (fs->win[BS_55AA+1] != 0xAA)) return 2;

but treating 'ptr' as a BYTE pointer but then casting a WORD pointer interpretation onto it and picking up that word for a single test of 55AA in theory reduces the complexity (and quite possibly the code size) of the test.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Cliff

Whats the best way to calculate a write and read time.

At moment i am using the JTAG debugger to program the device and also run it.

Would i be correct in saying that once i click on the play button, i get a bit more delay then the actual AVR has, due to PC etc.

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Whats the best way to calculate a write and read time.

Usual way to time stuff is... write a for() loop that does an operation (say) 10,000 times, time it with the sweep second hand on your watch then finally divide the time you measured by 10,000 (or whatever)

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks

I am trying to move a file from one folder to another. This is fairly easy using.

f_rename()

E.g.

f_rename("oldname.txt", "dir1/newname.txt");

Now if i hard code all the dir, it works. But if i want a under to specify the folder, how would i do that? At moment it is dir1, but i would like to choose or even have sub dire.

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the dirname is variable but the filename ("newname.txt") is fixed then why not just strcat() one onto the other before the f_rename()?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just did that before your post and its working.

Thanks

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

f_unlink, i can delete a file, but not a whole directory(folder).

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Normally you should be able to delete an EMPTY directory (it's the same in DOS). So you just have to delete all the files in it first and then the directory last. (possibly recursively)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

possibly recursively

Ah, yes. The fine art of recursive functions on an AVR.. :wink:

The code to delete a complete directory subtree is something that every CS student should have to do to get an exam. It's been a while since, but IIRC this is how it should go (sketchy, no specific OS but rather some "pseudo"-names for OS API functions that should be easily located for the specific case:

void removeDirectory(String path)
{
   foreach (file in path)
   {
      if (file.type == FILE) {
         delete(path+file.name);
      }
      else if file.type == DIRECTORY) {
         removeDirectory(path+file.name);
      }
      else {
         // Handle this gracefully...
      }
   }
   delete(path);
}

As I hinted, recursive functions and AVR don't always go well together. For an ATmega128 and a directory tree that isn't very deep it might work well, but...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan,

Surely the art of recursion is to keep the usage of locals to the absolute minimum necessary? If this removeDirectory() was creating a local filename buffer of 256 bytes for the longest possible LFN each time it were called then I agree it could eat RAM quickly, but this might actually be one of the few places where there's an argument for malloc() and only creating RAM buffers of exactly the required size?

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Surely the art of recursion is to keep the usage of locals to the absolute minimum necessary?

Not "the art", merely "one art". Others include eliminating "tail recursion". In the case above that might be possible, but it's at the end of the work day and my brain don't want to think about what would be needed. Certainly that all ordinary files are reported before sub-directories (in the enumeration / the foreach pseudo statement).

And if the system is really memory challenged, then even if you would have all directory names being just one character, you'd build up stack frames with return addresses etc.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got two questions..

1st

I have a network , with many nodes. Each file will have node information. So everytime a node changes its status the file will be updated.

If there is no change there will be no updat.

My AVR will have a RTC.

So everytime i compare my file to a node, i would like the time and date information to be replaced in the file. This should happen even if node has no change in its staus.

2nd

I need to scan a directory, i am using

f_readdir

What order will my scan be, is there away of reseting the counter or index value. So for example after scanning the directory it comes to the 5th file, but now it would like to scan from 0, rather then 6th entry.

Is there away of finding the total files, without scanning and keeping a count.

By the way i am declaring more Files, but the RAM does not increase. Even thou i have 4 files, not all will be opened at the same time. Worst case there will be 3, so would you say i should worry about files more then 3 being declared even thou no more then three will be opened at one given time.

Thanks

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

What order will my scan be

The order the file entries appear in the directory sectors. If the files are created consecutively with no deletions then it will be in creation order but as soon as you start deleting files their directory entry is set to 0xE5 and the next time the file system creates a file it will use the first 0xE5 entry it finds. So the order could become very mixed and near unpredictable.
Quote:
Is there away of finding the total files, without scanning and keeping a count.

Yes, you are the one creating and deleting. Each time you create one increment the counter and each time you delete one decrement it.
Quote:
By the way i am declaring more Files, but the RAM does not increase.

Simply not true.

FIL files[4];

occupies twice the space of

FIL files[2];

As this is a static allocation it's got nothing to do with whether the FIL structures are actually used by f_open'ing or not.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am declaring files like this

Fil file1,file2,file3

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In regards to scaning, i want to be able to index for my GUI,so once i select a file i should know what file is selected.

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello guys,

i've done a sketch, that you can have a look at my circuit.

The question is thou: How have you done it? What's eventually wrong with my circuit?

Thank you

Attachment(s): 

Last Edited: Wed. Oct 21, 2009 - 11:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you look at avr_mmc.png in the FatFs examples .zip file?

I just copied that almost exactly to be sure the code as delivered would just work. That included having the INS and WP support.

PS When I get a chance I am going to try that code you sent - my STK500 is tied up doing something else right now.

BTW you have read the Getting SD/MMC working tutorial haven't you?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cool, the tutorial seems quite interesting...
I will check this the next days.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've included all things from the Tutorial, but still: NO_FILESYSTEM. ARG!
Returnvalue still comes from:
if (fmt || LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* No valid FAT patition is found */
return FR_NO_FILESYSTEM;

fmt and LD_WORD... both have a value of zero.

zero for fmt means, that it is a FAT-partition-->looks good.
But the value of fs->win... should be 512, but it's zero too.

I should mention, that, because i don't use UART, i removed all files and functions related to this.

Update: Shit! if i put these 2 lines as comment, then the result is FR_INT_ERR. Damn, why can't this shit just work?!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello?

Anybody out there?

I created "abc.txt" on my card and set the f_open-flags to open_existing and read, but the same failure(no filesys) occurs.

do i need the RTC for my project? i hope not, because i deleted all parts concerning this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nope, you don't need RTC - you just stub the function where its interrogated to always return the same result. The upshot will be that all your files (if you ever manage to write them) will have the same date/time stamps.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, but I didn't understand your post, because there are several functions in rtc.c and i don't know, which function i have to stub. What's with these, with the I2C-interface? Delete?

Did you get my pm where i pleased you, to send me your project code?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How can i know if i am running on max speed.

I made 50 files that have 50 bytes of variables.

When i read the each file and output a certain variable from the file it takes few seconds for it to complete, does this timming sound correct?

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

does this timming sound correct?

No, reading a 50 byte file should be much quicker than that. Are you sure your code is not blocking elsewhere?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well i am using the standard UART to output.

But i can show you my reading code, what i do to read it later on today, once i get on my PC.

Maybe i am doing somthing wrong. Same happens when i am writing 50 bytes.

By the way i am reading like 50 files? Opening a file, reading the variable , displaying it, and then going to the next file.

Regards

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

displaying it,

Sounds like a long process. Cut that bit out and see how long the overall read of 50 files takes then divide by 50.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is there away to calculate accuratly how long it takes, According to my calculations

It takes 4 seconds, but lets say 5 seconds.

That is 5000ms.

So 5000ms for 50 files files, So each files is 100ms.

100ms for 50 bytes, so each byte is 2ms .

This also include all the UART.

Does this sound right?

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Like I say forget the UART as that's a huge block on performance. Just do:

uart_print("start\n");
for (i=0;i<5000;i++) {
 accessfile(i);
}
uart_print("finish\n");

then just time on your watch between start and finish then divide the elapsed seconds by 5000 (in this case) and that tells you how long accessfile() takes for one file.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will give this a try

Thanks

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi OK

I am now reading about 50 files, where each file has 50 bytes.

I have done the START and END display in the UART to indicate when to start the time and when to end the time.

My First test should it to be 1min and 17 secs, while the next took 30 seconds. I will explain bit futher down why there was such a big time improvment.

But does 30 secs sound right. This is 30 / 50 =0.6 seconds a file. Would this imply the time for 512bytes (sector) or 50 bytes(acutal data). If 50 bytes , then each byte takes 0.012 seconds.

Now my code

uart_puts_("START");
for (a=0;a<51;a++){
read_device(a);
}
uart_puts_("END");

Read_device, is reading a perticular file type.

int read_device(unsigned long long address)
{
int result;
UINT ret,*ret_add;
ret_add=&ret;
result=0;
//hexstring(name, (unsigned long long)address); 
//f_result = f_open(&file1,name, FA_READ |FA_OPEN_EXISTING); 
f_result = f_open(&file1,"a", FA_READ |FA_OPEN_EXISTING); 
if (f_result == FR_OK) { 
f_read(&file1,read_data,sizeof(read_databuffer),ret_add);
f_close(&file1);    	
result =1;
					}	
eturn result;
}

I am reading and closing the same file "a", rather then all the files. This is because the contents of the files are indenical. What this function is doing is, it reads long integer (hex file name) and converts it to string. Now i felt this hex to string was slowing things down. So i have commented out this call to this function.

Bu this is the function

char hexdig[] PROGMEM = { "0123456789ABCDEF" }; 
void hexstring(char * buf, unsigned long long n) { 
  uint8_t i; 
  buf[16] = 0; 
  for (i=0; i<16; i++) { 
    buf[15-i] = pgm_read_word(&hexdig[n & 0x0f]); 
    n >>= 4; 
			 } 								} 

So does this sound correct, in regards to my time issue?

Regards

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Would this imply the time for 512bytes (sector) or 50 bytes(acutal data)

You are kidding yourself if you think there's only one 512 byte sector read involved in reading 50 bytes from a file! Try putting a UART debug output that displays each time disk_read() in mmc.c is called and then call your read_device() function just once.

Using 50 files each of 50 bytes may get FatFs to do the indexing for you but it is HUGELY inefficient compared to one file of 2,500 bytes where you index the data yourself.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So would you say all my timing is all correct.

I wounder if changed the freg from 8mhz to 20 mhz, will it make a differnce or does this FATfs scale the freq down.

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was orginally thinking about keeping all data in one file and then have very large datastructure with all nessary information.

This way maybe every 200 byte could be a seen as new entry(compared to new file).

My only problem is what variable type to use if i want to read say the middle of 10mb file, how would i represent that i want to read the byte that is 5mb. What variable would be big enough?

Regards

DJ

Thanks

Regards

DJ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should get some good books about learning C if the answer to that kind of question is not obvious. Personally I'd fseek to some multiple of sizeof(struct) and then cast a struct interpretation onto the buffer-full just read. (maybe different struct types if the data differs). For example:

typedef struct {
 int rec_num;
 char name[40];
 int age;
 int year_birth;
 int month_birth;
 int day_birth;
} data_record_t;

...
data_record_t * pdata;
int rec_size = sizeof(* pdata);
uint8_t buffer[N];

fin = fopen(file, "rb");
fseek(fin, rec_size*rec_N);
fread(buffer, rec_size, fin);
pdata = (data_record_t *)&buffer;
if (pdata->year_birth> 1970) {
 ...
}

Pages