strptime/getdate AVR implementation

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I noticed there is no

https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=26326&highlight=mktime

Jim

Jim Brain

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

er, if you had such library routines, it begs the issue of where does the date/time reference come from? Clock chip? Internet? Osmosis?

What I've done, via the ethernet interface on my AVR dev. system, is fetch the date, time, daylight savings status, etc. from the (USA) NIST web site for the DayTime (RFC) protocol. That response is in ASCII text, much simpler.

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

I don;t need a RTC reference or the current date/time. What I have coming into the unit is two dates of the format MM/DD/YY HH:MM:SS [A|P]M and a date/time from a FAT directory entry. I would like to use getdate or strptime to convert the former two to time_t objects and the second from a time structure to a time_t so I can verify that the 3rd is in between the 1st and second values.

he unit is standalone, so there is no time source, and even if there way, it won't help.

Jim

Jim Brain

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

Well if it's FAT date/time you want to decode then because bytes 0x0E/0x0F is (little endian):

bits
15-11 Hours (0-23) 
10-5  Minutes (0-59) 
4-0   Seconds/2 (0-29) 

maybe use something like:

hours = (byteF & 0xF8) >> 3;
minutes = ((byteF & 7) << 3) | ((byteE & 0xE0) >> 5);
secs = (byteE & 0x1F) * 2; // or << 1

(untested - I just scribbled the 0's and 1's on the back of an envelope!)

The date is in bytes 0x10 and 0x11 as:

bits
15-9 Year (0 = 1980, 127 = 2107) 
8-5  Month (1 = January, 12 = December) 
4-0  Day (1 - 31)

so I think the following would work:

year = ((byte11 & 0xFE) >> 1) + 1980;
month = ((byte11 & 1) << 3) | ((byte10 & 0xE0) >> 5));
day = byte11 & 0x1F;

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

PS I just realised I HAVE written this before now:

				fsize = cjl_sec_buffer[i+28] + (cjl_sec_buffer[i+29] << 8) + (cjl_sec_buffer[i+30] << 16) + (cjl_sec_buffer[i+31] << 24);
				sec = (cjl_sec_buffer[i+22] & 0x1F) * 2;
				min = ((cjl_sec_buffer[i+22] & 0xE0)>>5) +  ((cjl_sec_buffer[i+23] & 0x07)<<3);
				hour = ((cjl_sec_buffer[i+23] & 0xF8)>>3); 
				date = cjl_sec_buffer[i+24] & 0x1F;
				mnum = ((cjl_sec_buffer[i+24] & 0xE0)>>5) + ((cjl_sec_buffer[i+25] & 0x01)<<3);
				strcpy(month, months[mnum-1]);
				year = ((cjl_sec_buffer[i+25] & 0xFE)>>1) + 1980;

(that is proven, working code)

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

clawson wrote:

hours = (byteF & 0xF8) >> 3;
minutes = ((byteF & 7) << 3) | ((byteE & 0xE0) >> 5);
secs = (byteE & 0x1F) * 2; // or << 1
year = ((byte11 & 0xFE) >> 1) + 1980;
month = ((byte11 & 1) << 3) | ((byte10 & 0xE0) >> 5));
day = byte11 & 0x1F;

For reference, FatFs code for the above:

    dent->year  = (finfo.fdate >> 9) + 80;
    dent->month = (finfo.fdate >> 5) & 0x0f;
    dent->day   = finfo.fdate & 0x1f;

    dent->hour   = finfo.ftime >> 11;
    dent->minute = (finfo.ftime >> 5) & 0x3f;
    dent->second = (finfo.ftime & 0x1f) << 1;

Thus, while I appreciate the code, I have the FAT code working, but I need something to parse "04/28/2008 10:00:00 AM" into a time_t and something to turn the discrete FAT values into a time_t. I can probably roll the latter (mktime()), but the former is a chore (strptime/getdate).

Jim

Jim Brain

Last Edited: Tue. Apr 29, 2008 - 02:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm guessing that in FatFs's code the fdate and ftime fields are "unsigned int" and map to 0x0E/0x0F and 0x10/0x11 in the FAT data? This will probably work on an AVR because it (certainly in GCC variant) like the Intelx86 from which FAT comes are both little endian.

Unfortunately the code I wrote was for a big endian MIPS4100 processor so I didn't have that luxury which is why I accessed the bytes individually and did all the shifts - that access method is agnostic of the processor's endianism.

Cliff

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

FatFs takes care of switching the bytes around so that the uint always represents the data in the above way, regardless of endianness.

Jim

Jim Brain