Index: fat16_config.h =================================================================== --- fat16_config.h (Revision 94) +++ fat16_config.h (Arbeitskopie) @@ -30,6 +30,30 @@ /** * \ingroup fat16_config + * Controls FAT16 date and time support. + * + * Set to 1 to enable FAT16 date and time stamping support. + */ +#define FAT16_DATETIME_SUPPORT 1 + +/** + * \ingroup fat16_config + * Determines the function used for retrieving current date and time. + * + * Used when FAT16_DATETIME_SUPPORT is 1. + */ +#define fat16_get_datetime(year, month, day, hour, min, sec) \ +{ \ + (year) = 2007; \ + (month) = 1; \ + (day) = 1; \ + (hour) = 0; \ + (min) = 0; \ + (sec) = 0; \ +} + +/** + * \ingroup fat16_config * Maximum number of filesystem handles. */ #define FAT16_FS_COUNT 1 Index: fat16.c =================================================================== --- fat16.c (Revision 99) +++ fat16.c (Arbeitskopie) @@ -198,6 +198,9 @@ static uint8_t fat16_get_fs_free_callback(uint8_t* buffer, uint32_t offset, void* p); +static void fat16_set_file_creation_date(struct fat16_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day); +static void fat16_set_file_creation_time(struct fat16_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec); + /** * \ingroup fat16_fs * Opens a FAT16 filesystem. @@ -630,6 +633,14 @@ ((uint32_t) raw_entry[30] << 16) | ((uint32_t) raw_entry[31] << 24); +#if FAT16_DATETIME_SUPPORT + dir_entry->creation_time_tenths = raw_entry[13]; + dir_entry->creation_time = ((uint16_t) raw_entry[14]) | + ((uint16_t) raw_entry[15] << 8); + dir_entry->creation_date = ((uint16_t) raw_entry[16]) | + ((uint16_t) raw_entry[17] << 8); +#endif + return 2; } } @@ -1721,6 +1732,13 @@ /* fill directory entry buffer */ memset(&buffer[11], 0, sizeof(buffer) - 11); buffer[0x0b] = dir_entry->attributes; +#if FAT16_DATETIME_SUPPORT + buffer[0x0d] = dir_entry->creation_time_tenths; + buffer[0x0e] = (dir_entry->creation_time >> 0) & 0xff; + buffer[0x0f] = (dir_entry->creation_time >> 8) & 0xff; + buffer[0x10] = (dir_entry->creation_date >> 0) & 0xff; + buffer[0x11] = (dir_entry->creation_date >> 8) & 0xff; +#endif buffer[0x1a] = (dir_entry->cluster >> 0) & 0xff; buffer[0x1b] = (dir_entry->cluster >> 8) & 0xff; buffer[0x1c] = (dir_entry->file_size >> 0) & 0xff; @@ -1840,9 +1858,24 @@ struct fat16_fs_struct* fs = parent->fs; + /* prepare directory entry with values already known */ memset(dir_entry, 0, sizeof(*dir_entry)); strncpy(dir_entry->long_name, file, sizeof(dir_entry->long_name) - 1); +#if FAT16_DATETIME_SUPPORT + { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + fat16_get_datetime(year, month, day, hour, min, sec); + fat16_set_file_creation_date(dir_entry, year, month, day); + fat16_set_file_creation_time(dir_entry, hour, min, sec); + } +#endif + /* find place where to store directory entry */ if(!(dir_entry->entry_offset = fat16_find_offset_for_dir_entry(fs, parent, dir_entry))) return 0; @@ -1962,7 +1995,21 @@ memset(dir_entry, 0, sizeof(*dir_entry)); dir_entry->attributes = FAT16_ATTRIB_DIR; +#if FAT16_DATETIME_SUPPORT + { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + fat16_get_datetime(year, month, day, hour, min, sec); + fat16_set_file_creation_date(dir_entry, year, month, day); + fat16_set_file_creation_time(dir_entry, hour, min, sec); + } +#endif + /* create "." directory self reference */ dir_entry->entry_offset = fs->header.cluster_zero_offset + (uint32_t) (dir_cluster - 2) * fs->header.cluster_size; @@ -2029,6 +2076,73 @@ #endif /** + * \ingroup fat16_file + * Returns the creation date of a file. + */ +void fat16_get_file_creation_date(const struct fat16_dir_entry_struct* dir_entry, uint16_t* year, uint8_t* month, uint8_t* day) +{ +#if FAT16_DATETIME_SUPPORT + if(!dir_entry) + return; + + *year = 1980 + ((dir_entry->creation_date >> 9) & 0x7f); + *month = (dir_entry->creation_date >> 5) & 0x0f; + *day = (dir_entry->creation_date >> 0) & 0x1f; +#endif +} + +/** + * \ingroup fat16_file + * Returns the creation time of a file. + */ +void fat16_get_file_creation_time(const struct fat16_dir_entry_struct* dir_entry, uint8_t* hour, uint8_t* min, uint8_t* sec) +{ +#if FAT16_DATETIME_SUPPORT + if(!dir_entry) + return; + + *hour = (dir_entry->creation_time >> 11) & 0x1f; + *min = (dir_entry->creation_time >> 5) & 0x3f; + *sec = ((dir_entry->creation_time >> 0) & 0x1f) * 2 + dir_entry->creation_time_tenths / 100; +#endif +} + +/** + * \ingroup fat16_file + * Sets the creation time of a date. + */ +void fat16_set_file_creation_date(struct fat16_dir_entry_struct* dir_entry, uint16_t year, uint8_t month, uint8_t day) +{ +#if FAT16_DATETIME_SUPPORT + if(!dir_entry) + return; + + dir_entry->creation_date = + ((year - 1980) << 9) | + ((uint16_t) month << 5) | + ((uint16_t) day << 0); +#endif +} + +/** + * \ingroup fat16_file + * Sets the creation time of a file. + */ +void fat16_set_file_creation_time(struct fat16_dir_entry_struct* dir_entry, uint8_t hour, uint8_t min, uint8_t sec) +{ +#if FAT16_DATETIME_SUPPORT + if(!dir_entry) + return; + + dir_entry->creation_time = + ((uint16_t) hour << 11) | + ((uint16_t) min << 5) | + ((uint16_t) sec >> 1) ; + dir_entry->creation_time_tenths = (sec & 0x01) * 100; +#endif +} + +/** * \ingroup fat16_fs * Returns the amount of total storage capacity of the filesystem in bytes. * Index: fat16.h =================================================================== --- fat16.h (Revision 94) +++ fat16.h (Arbeitskopie) @@ -10,6 +10,8 @@ #ifndef FAT16_H #define FAT16_H +#include "fat16_config.h" + #include /** @@ -68,6 +70,13 @@ char long_name[32]; /** The file's attributes. Mask of the FAT16_ATTRIB_* constants. */ uint8_t attributes; +#if FAT16_DATETIME_SUPPORT + /** Compressed representation of creation time. */ + uint8_t creation_time_tenths; + uint16_t creation_time; + /** Compressed representation of creation date. */ + uint16_t creation_date; +#endif /** The cluster in which the file's first byte resides. */ uint16_t cluster; /** The file's size. */ @@ -96,6 +105,9 @@ uint8_t fat16_create_dir(struct fat16_dir_struct* parent, const char* dir, struct fat16_dir_entry_struct* dir_entry); #define fat16_delete_dir fat16_delete_file +void fat16_get_file_creation_date(const struct fat16_dir_entry_struct* dir_entry, uint16_t* year, uint8_t* month, uint8_t* day); +void fat16_get_file_creation_time(const struct fat16_dir_entry_struct* dir_entry, uint8_t* hour, uint8_t* min, uint8_t* sec); + uint8_t fat16_get_dir_entry_of_path(struct fat16_fs_struct* fs, const char* path, struct fat16_dir_entry_struct* dir_entry); uint32_t fat16_get_fs_size(const struct fat16_fs_struct* fs);