34 #if USE_DYNAMIC_MEMORY 85 #define FAT16_CLUSTER_FREE 0x0000 86 #define FAT16_CLUSTER_RESERVED_MIN 0xfff0 87 #define FAT16_CLUSTER_RESERVED_MAX 0xfff6 88 #define FAT16_CLUSTER_BAD 0xfff7 89 #define FAT16_CLUSTER_LAST_MIN 0xfff8 90 #define FAT16_CLUSTER_LAST_MAX 0xffff 92 #define FAT32_CLUSTER_FREE 0x00000000 93 #define FAT32_CLUSTER_RESERVED_MIN 0x0ffffff0 94 #define FAT32_CLUSTER_RESERVED_MAX 0x0ffffff6 95 #define FAT32_CLUSTER_BAD 0x0ffffff7 96 #define FAT32_CLUSTER_LAST_MIN 0x0ffffff8 97 #define FAT32_CLUSTER_LAST_MAX 0x0fffffff 99 #define FAT_DIRENTRY_DELETED 0xe5 100 #define FAT_DIRENTRY_LFNLAST (1 << 6) 101 #define FAT_DIRENTRY_LFNSEQMASK ((1 << 6) - 1) 159 uint16_t sector_size;
160 uint16_t cluster_size;
162 offset_t cluster_zero_offset;
164 offset_t root_dir_offset;
165 #if FAT_FAT32_SUPPORT 166 cluster_t root_dir_cluster;
174 cluster_t cluster_free;
182 cluster_t pos_cluster;
189 cluster_t entry_cluster;
196 uintptr_t bytes_read;
205 cluster_t cluster_count;
206 uintptr_t buffer_size;
209 #if !USE_DYNAMIC_MEMORY 224 #if FAT_FAT32_SUPPORT 228 #if FAT_WRITE_SUPPORT 236 #if FAT_DATETIME_SUPPORT 260 #if USE_DYNAMIC_MEMORY 269 if ( !fs->partition )
break;
273 if ( i >= FAT_FS_COUNT )
return 0;
276 memset ( fs, 0,
sizeof(*fs) );
278 fs->partition = partition;
281 #if USE_DYNAMIC_MEMORY 306 #if USE_DYNAMIC_MEMORY 325 if ( !partition )
return 0;
328 #if FAT_FAT32_SUPPORT 333 offset_t partition_offset = (offset_t) partition->
offset * 512;
334 if ( !partition->
device_read ( partition_offset + 0x0b, buffer,
sizeof(buffer) ) )
return 0;
336 uint16_t bytes_per_sector =
read16( &buffer[0x00] );
337 uint16_t reserved_sectors =
read16( &buffer[0x03] );
338 uint8_t sectors_per_cluster = buffer[0x02];
339 uint8_t fat_copies = buffer[0x05];
340 uint16_t max_root_entries =
read16( &buffer[0x06] );
341 uint16_t sector_count_16 =
read16( &buffer[0x08] );
342 uint16_t sectors_per_fat =
read16( &buffer[0x0b] );
343 uint32_t sector_count =
read32( &buffer[0x15] );
344 #if FAT_FAT32_SUPPORT 345 uint32_t sectors_per_fat32 =
read32( &buffer[0x19] );
346 uint32_t cluster_root_dir =
read32( &buffer[0x21] );
349 if ( sector_count == 0 )
351 if ( sector_count_16 == 0 )
355 sector_count = sector_count_16;
357 #if FAT_FAT32_SUPPORT 358 if ( sectors_per_fat != 0 )
359 sectors_per_fat32 = sectors_per_fat;
360 else if ( sectors_per_fat32 == 0 )
364 if(sectors_per_fat == 0)
370 uint32_t data_sector_count = sector_count - reserved_sectors
371 #if FAT_FAT32_SUPPORT 372 - sectors_per_fat32 * fat_copies
374 - (uint32_t) sectors_per_fat * fat_copies
376 - ((max_root_entries * 32 + bytes_per_sector - 1) / bytes_per_sector);
377 uint32_t data_cluster_count = data_sector_count / sectors_per_cluster;
378 if ( data_cluster_count < 4085 )
381 else if ( data_cluster_count < 65525 )
390 memset ( header, 0,
sizeof(*header) );
392 header->size = (offset_t) sector_count * bytes_per_sector;
397 (offset_t) reserved_sectors * bytes_per_sector;
400 header->sector_size = bytes_per_sector;
401 header->cluster_size = (uint16_t) bytes_per_sector * sectors_per_cluster;
403 #if FAT_FAT32_SUPPORT 407 header->root_dir_offset =
410 (offset_t) fat_copies * sectors_per_fat * bytes_per_sector;
412 header->cluster_zero_offset =
413 header->root_dir_offset +
415 (offset_t) max_root_entries * 32;
417 #if FAT_FAT32_SUPPORT 420 header->cluster_zero_offset =
423 (offset_t) fat_copies * sectors_per_fat32 * bytes_per_sector;
425 header->root_dir_cluster = cluster_root_dir;
446 if ( !fs || cluster_num < 2 )
return 0;
448 #if FAT_FAT32_SUPPORT 453 if ( !fs->partition->
device_read ( fs->header.fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) ) )
return 0;
456 cluster_num = ltoh32( fat_entry );
458 if ( cluster_num == FAT32_CLUSTER_FREE || cluster_num == FAT32_CLUSTER_BAD || (cluster_num >= FAT32_CLUSTER_RESERVED_MIN && cluster_num <= FAT32_CLUSTER_RESERVED_MAX)
459 || (cluster_num >= FAT32_CLUSTER_LAST_MIN && cluster_num <= FAT32_CLUSTER_LAST_MAX) )
return 0;
466 if ( !fs->partition->
device_read ( fs->header.fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) ) )
return 0;
469 cluster_num = ltoh16( fat_entry );
471 if ( cluster_num == FAT16_CLUSTER_FREE || cluster_num == FAT16_CLUSTER_BAD || (cluster_num >= FAT16_CLUSTER_RESERVED_MIN && cluster_num <= FAT16_CLUSTER_RESERVED_MAX)
472 || (cluster_num >= FAT16_CLUSTER_LAST_MIN && cluster_num <= FAT16_CLUSTER_LAST_MAX) )
return 0;
478 #if DOXYGEN || FAT_WRITE_SUPPORT 496 offset_t fat_offset = fs->header.fat_offset;
497 cluster_t count_left = count;
498 cluster_t cluster_current = fs->cluster_free;
499 cluster_t cluster_next = 0;
500 cluster_t cluster_count;
501 uint16_t fat_entry16;
502 #if FAT_FAT32_SUPPORT 503 uint32_t fat_entry32;
507 cluster_count = fs->header.fat_size /
sizeof(fat_entry32);
510 cluster_count = fs->header.fat_size /
sizeof(fat_entry16);
512 fs->cluster_free = 0;
513 for ( cluster_t cluster_left = cluster_count; cluster_left > 0; --cluster_left, ++cluster_current )
515 if ( cluster_current < 2 || cluster_current >= cluster_count ) cluster_current = 2;
517 #if FAT_FAT32_SUPPORT 520 if ( !device_read ( fat_offset + (offset_t) cluster_current *
sizeof(fat_entry32), (uint8_t*) &fat_entry32,
sizeof(fat_entry32) ) )
return 0;
525 if ( !device_read ( fat_offset + (offset_t) cluster_current *
sizeof(fat_entry16), (uint8_t*) &fat_entry16,
sizeof(fat_entry16) ) )
return 0;
528 #if FAT_FAT32_SUPPORT 532 if ( fat_entry32 !=
HTOL32( FAT32_CLUSTER_FREE ) )
continue;
538 if ( count_left == 0 )
540 fs->cluster_free = cluster_current;
545 if ( cluster_next == 0 )
546 fat_entry32 =
HTOL32( FAT32_CLUSTER_LAST_MAX );
548 fat_entry32 = htol32( cluster_next );
550 if ( !device_write ( fat_offset + (offset_t) cluster_current *
sizeof(fat_entry32), (uint8_t*) &fat_entry32,
sizeof(fat_entry32) ) )
break;
556 if ( fat_entry16 !=
HTOL16( FAT16_CLUSTER_FREE ) )
continue;
562 if ( count_left == 0 )
564 fs->cluster_free = cluster_current;
569 if ( cluster_next == 0 )
570 fat_entry16 =
HTOL16( FAT16_CLUSTER_LAST_MAX );
572 fat_entry16 = htol16( (uint16_t ) cluster_next );
574 if ( !device_write ( fat_offset + (offset_t) cluster_current *
sizeof(fat_entry16), (uint8_t*) &fat_entry16,
sizeof(fat_entry16) ) )
break;
577 cluster_next = cluster_current;
583 if ( count_left > 0 )
break;
588 if ( cluster_num >= 2 )
590 #if FAT_FAT32_SUPPORT 593 fat_entry32 = htol32( cluster_next );
595 if ( !device_write ( fat_offset + (offset_t) cluster_num *
sizeof(fat_entry32), (uint8_t*) &fat_entry32,
sizeof(fat_entry32) ) )
break;
600 fat_entry16 = htol16( (uint16_t ) cluster_next );
602 if ( !device_write ( fat_offset + (offset_t) cluster_num *
sizeof(fat_entry16), (uint8_t*) &fat_entry16,
sizeof(fat_entry16) ) )
break;
620 #if DOXYGEN || FAT_WRITE_SUPPORT 640 if ( !fs || cluster_num < 2 )
return 0;
642 offset_t fat_offset = fs->header.fat_offset;
643 #if FAT_FAT32_SUPPORT 647 while ( cluster_num )
649 if ( !fs->partition->
device_read ( fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) ) )
return 0;
652 uint32_t cluster_num_next = ltoh32( fat_entry );
654 if ( cluster_num_next == FAT32_CLUSTER_FREE )
return 1;
655 if ( cluster_num_next == FAT32_CLUSTER_BAD || (cluster_num_next >= FAT32_CLUSTER_RESERVED_MIN && cluster_num_next <= FAT32_CLUSTER_RESERVED_MAX) )
return 0;
656 if ( cluster_num_next >= FAT32_CLUSTER_LAST_MIN && cluster_num_next <= FAT32_CLUSTER_LAST_MAX ) cluster_num_next = 0;
661 if ( !fs->cluster_free ) fs->cluster_free = cluster_num;
664 fat_entry =
HTOL32( FAT32_CLUSTER_FREE );
665 fs->partition->
device_write ( fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) );
671 cluster_num = cluster_num_next;
678 while ( cluster_num )
680 if ( !fs->partition->
device_read ( fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) ) )
return 0;
683 uint16_t cluster_num_next = ltoh16( fat_entry );
685 if ( cluster_num_next == FAT16_CLUSTER_FREE )
return 1;
686 if ( cluster_num_next == FAT16_CLUSTER_BAD || (cluster_num_next >= FAT16_CLUSTER_RESERVED_MIN && cluster_num_next <= FAT16_CLUSTER_RESERVED_MAX) )
return 0;
687 if ( cluster_num_next >= FAT16_CLUSTER_LAST_MIN && cluster_num_next <= FAT16_CLUSTER_LAST_MAX ) cluster_num_next = 0;
690 fat_entry =
HTOL16( FAT16_CLUSTER_FREE );
691 fs->partition->
device_write ( fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) );
697 cluster_num = cluster_num_next;
705 #if DOXYGEN || FAT_WRITE_SUPPORT 720 if ( !fs || cluster_num < 2 )
return 0;
726 #if FAT_FAT32_SUPPORT 729 uint32_t fat_entry =
HTOL32( FAT32_CLUSTER_LAST_MAX );
730 if ( !fs->partition->
device_write ( fs->header.fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) ) )
return 0;
735 uint16_t fat_entry =
HTOL16( FAT16_CLUSTER_LAST_MAX );
736 if ( !fs->partition->
device_write ( fs->header.fat_offset + (offset_t) cluster_num *
sizeof(fat_entry), (uint8_t*) &fat_entry,
sizeof(fat_entry) ) )
return 0;
740 if ( cluster_num_next )
747 #if DOXYGEN || FAT_WRITE_SUPPORT 760 if ( cluster_num < 2 )
return 0;
765 memset ( zero, 0,
sizeof(zero) );
770 #if DOXYGEN || FAT_WRITE_SUPPORT 791 if ( !fs || cluster_num < 2 )
return 0;
793 return fs->header.cluster_zero_offset + (offset_t) (cluster_num - 2) * fs->header.cluster_size;
810 if ( !fs || !path || path[0] ==
'\0' || !dir_entry )
return 0;
812 if ( path[0] ==
'/' ) ++path;
815 memset ( dir_entry, 0,
sizeof(*dir_entry) );
820 if ( path[0] ==
'\0' )
return 1;
826 const char* sub_path = strchr ( path,
'/' );
827 uint8_t length_to_sep;
830 length_to_sep = sub_path - path;
835 length_to_sep = strlen ( path );
836 sub_path = path + length_to_sep;
843 if ( (strlen ( dir_entry->
long_name ) != length_to_sep || strncmp ( path, dir_entry->
long_name, length_to_sep ) != 0) )
continue;
848 if ( path[length_to_sep] ==
'\0' )
882 #if USE_DYNAMIC_MEMORY 891 if ( !fd->fs )
break;
895 if ( i >= FAT_FILE_COUNT )
return 0;
898 memcpy ( &fd->dir_entry, dir_entry,
sizeof(*dir_entry) );
901 fd->pos_cluster = dir_entry->
cluster;
917 #if FAT_DELAY_DIRENTRY_UPDATE 922 #if USE_DYNAMIC_MEMORY 945 if ( !fd || !buffer || buffer_len < 1 )
return -1;
948 if ( fd->pos + buffer_len > fd->dir_entry.
file_size ) buffer_len = fd->dir_entry.
file_size - fd->pos;
949 if ( buffer_len == 0 )
return 0;
951 uint16_t cluster_size = fd->fs->header.cluster_size;
952 cluster_t cluster_num = fd->pos_cluster;
953 uintptr_t buffer_left = buffer_len;
954 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1));
959 cluster_num = fd->dir_entry.
cluster;
971 uint32_t pos = fd->pos;
972 while ( pos >= cluster_size )
976 if ( !cluster_num )
return -1;
985 offset_t cluster_offset =
fat_cluster_offset ( fd->fs, cluster_num ) + first_cluster_offset;
986 uint16_t copy_length = cluster_size - first_cluster_offset;
987 if ( copy_length > buffer_left ) copy_length = buffer_left;
990 if ( !fd->fs->partition->
device_read ( cluster_offset, buffer, copy_length ) )
return buffer_len - buffer_left;
993 buffer += copy_length;
994 buffer_left -= copy_length;
995 fd->pos += copy_length;
997 if ( first_cluster_offset + copy_length >= cluster_size )
1002 first_cluster_offset = 0;
1006 fd->pos_cluster = 0;
1007 return buffer_len - buffer_left;
1011 fd->pos_cluster = cluster_num;
1014 while ( buffer_left > 0 );
1019 #if DOXYGEN || FAT_WRITE_SUPPORT 1035 if ( !fd || !buffer || buffer_len < 1 )
return -1;
1036 if ( fd->pos > fd->dir_entry.
file_size )
return -1;
1038 uint16_t cluster_size = fd->fs->header.cluster_size;
1039 cluster_t cluster_num = fd->pos_cluster;
1040 uintptr_t buffer_left = buffer_len;
1041 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1));
1046 cluster_num = fd->dir_entry.
cluster;
1054 if ( !cluster_num )
return 0;
1064 uint32_t pos = fd->pos;
1065 cluster_t cluster_num_next;
1066 while ( pos >= cluster_size )
1068 pos -= cluster_size;
1070 if ( !cluster_num_next )
1072 if ( pos != 0 )
return -1;
1076 if ( !cluster_num_next )
return 0;
1079 cluster_num = cluster_num_next;
1088 offset_t cluster_offset =
fat_cluster_offset ( fd->fs, cluster_num ) + first_cluster_offset;
1089 uint16_t write_length = cluster_size - first_cluster_offset;
1090 if ( write_length > buffer_left ) write_length = buffer_left;
1093 if ( !fd->fs->partition->
device_write ( cluster_offset, buffer, write_length ) )
break;
1096 buffer += write_length;
1097 buffer_left -= write_length;
1098 fd->pos += write_length;
1100 if ( first_cluster_offset + write_length >= cluster_size )
1104 if ( !cluster_num_next && buffer_left > 0 )
1107 if ( !cluster_num_next )
1109 fd->pos_cluster = 0;
1113 cluster_num = cluster_num_next;
1114 first_cluster_offset = 0;
1117 fd->pos_cluster = cluster_num;
1120 while ( buffer_left > 0 );
1123 if ( fd->pos > fd->dir_entry.
file_size )
1125 #if !FAT_DELAY_DIRENTRY_UPDATE 1126 uint32_t size_old = fd->dir_entry.
file_size;
1132 #if !FAT_DELAY_DIRENTRY_UPDATE 1140 buffer_left = fd->pos - size_old;
1146 return buffer_len - buffer_left;
1188 if ( !fd || !offset )
return 0;
1190 uint32_t new_pos = fd->pos;
1200 new_pos = fd->dir_entry.
file_size + *offset;
1213 fd->pos_cluster = 0;
1215 *offset = (int32_t) new_pos;
1219 #if DOXYGEN || FAT_WRITE_SUPPORT 1241 if ( !fd )
return 0;
1243 cluster_t cluster_num = fd->dir_entry.
cluster;
1244 uint16_t cluster_size = fd->fs->header.cluster_size;
1245 uint32_t size_new = size;
1249 if ( cluster_num == 0 && size_new == 0 )
1254 while ( size_new > cluster_size )
1258 if ( cluster_num_next )
1260 cluster_num = cluster_num_next;
1261 size_new -= cluster_size;
1269 if ( size_new > cluster_size || cluster_num == 0 )
1274 cluster_t cluster_count = (size_new + cluster_size - 1) / cluster_size;
1276 if ( !cluster_new_chain )
return 0;
1280 cluster_num = cluster_new_chain;
1281 fd->dir_entry.
cluster = cluster_num;
1287 if ( size == 0 ) fd->dir_entry.
cluster = 0;
1295 else if ( size_new <= cluster_size )
1305 if ( size < fd->pos )
1308 fd->pos_cluster = 0;
1328 #if USE_DYNAMIC_MEMORY 1337 if ( !dd->fs )
break;
1341 if ( i >= FAT_DIR_COUNT )
return 0;
1344 memcpy ( &dd->dir_entry, dir_entry,
sizeof(*dir_entry) );
1346 dd->entry_cluster = dir_entry->
cluster;
1347 dd->entry_offset = 0;
1366 #if USE_DYNAMIC_MEMORY 1384 if ( !dd || !dir_entry )
return 0;
1389 uint16_t cluster_size = header->cluster_size;
1390 cluster_t cluster_num = dd->entry_cluster;
1391 uint16_t cluster_offset = dd->entry_offset;
1394 if ( cluster_offset >= cluster_size )
1406 memset ( &arg, 0,
sizeof(arg) );
1407 memset ( dir_entry, 0,
sizeof(*dir_entry) );
1408 arg.dir_entry = dir_entry;
1411 if ( cluster_num == 0 )
1413 #if FAT_FAT32_SUPPORT 1415 cluster_num = header->root_dir_cluster;
1418 cluster_size = header->cluster_zero_offset - header->root_dir_offset;
1423 while ( !arg.finished )
1426 uint16_t cluster_left = cluster_size - cluster_offset;
1427 offset_t pos = cluster_offset;
1428 if ( cluster_num == 0 )
1429 pos += header->root_dir_offset;
1436 cluster_offset += arg.bytes_read;
1438 if ( cluster_offset >= cluster_size )
1450 if ( !arg.finished )
1470 dd->entry_cluster = cluster_num;
1471 dd->entry_offset = cluster_offset;
1473 return arg.finished;
1489 if ( !dd )
return 0;
1491 dd->entry_cluster = dd->dir_entry.
cluster;
1492 dd->entry_offset = 0;
1520 arg->bytes_read += 32;
1523 if ( buffer[0] == FAT_DIRENTRY_DELETED || !buffer[0] )
1531 #if !FAT_LFN_SUPPORT 1533 if(buffer[11] == 0x0f)
1539 if ( buffer[11] == 0x0f )
1542 if ( arg->checksum == 0 || arg->checksum != buffer[13] )
1545 memset ( dir_entry, 0,
sizeof(*dir_entry) );
1547 arg->checksum = buffer[13];
1555 uint16_t char_offset = ((buffer[0] & 0x3f) - 1) * 13;
1556 const uint8_t char_mapping[] = { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
1557 for ( uint8_t i = 0; i <= 12 && char_offset + i <
sizeof(dir_entry->
long_name) - 1; ++i )
1558 long_name[char_offset + i] = buffer[char_mapping[i]];
1571 memset ( dir_entry, 0,
sizeof(*dir_entry) );
1575 for ( i = 0; i < 8; ++i )
1577 if ( buffer[i] ==
' ' )
break;
1578 long_name[i] = buffer[i];
1585 if ( (buffer[12] & 0x08) && buffer[i] >=
'A' && buffer[i] <=
'Z' ) long_name[i] +=
'a' -
'A';
1587 if ( long_name[0] == 0x05 ) long_name[0] = (char) FAT_DIRENTRY_DELETED;
1589 if ( buffer[8] !=
' ' )
1591 long_name[i++] =
'.';
1594 for ( ; j < 11; ++j )
1596 if ( buffer[j] ==
' ' )
break;
1597 long_name[i] = buffer[j];
1602 if ( (buffer[12] & 0x10) && buffer[j] >=
'A' && buffer[j] <=
'Z' ) long_name[i] +=
'a' -
'A';
1608 long_name[i] =
'\0';
1614 #if FAT_FAT32_SUPPORT 1615 dir_entry->
cluster |= ((cluster_t)
read16( &buffer[20] )) << 16;
1619 #if FAT_DATETIME_SUPPORT 1629 #if DOXYGEN || FAT_LFN_SUPPORT 1640 uint8_t checksum = file_name_83[0];
1641 for ( uint8_t i = 1; i < 11; ++i )
1642 checksum = ((checksum >> 1) | (checksum << 7)) + file_name_83[i];
1648 #if DOXYGEN || FAT_WRITE_SUPPORT 1660 if ( !fs || !dir_entry )
return 0;
1664 uint8_t free_dir_entries_needed = (strlen ( dir_entry->
long_name ) + 12) / 13 + 1;
1665 uint8_t free_dir_entries_found = 0;
1667 cluster_t cluster_num = parent->dir_entry.
cluster;
1668 offset_t dir_entry_offset = 0;
1669 offset_t offset = 0;
1670 offset_t offset_to = 0;
1671 #if FAT_FAT32_SUPPORT 1675 if ( cluster_num == 0 )
1677 #if FAT_FAT32_SUPPORT 1680 cluster_num = fs->header.root_dir_cluster;
1686 offset = fs->header.root_dir_offset;
1687 offset_to = fs->header.cluster_zero_offset;
1688 dir_entry_offset = offset;
1694 if ( offset == offset_to )
1696 if ( cluster_num == 0 )
1709 if ( !cluster_next )
1712 if ( !cluster_next )
return 0;
1715 dir_entry_offset = fs->header.cluster_zero_offset + (offset_t) (cluster_next - 2) * fs->header.cluster_size;
1722 cluster_num = cluster_next;
1726 offset_to = offset + fs->header.cluster_size;
1727 dir_entry_offset = offset;
1729 free_dir_entries_found = 0;
1735 if ( !fs->partition->
device_read ( offset, &first_char,
sizeof(first_char) ) )
return 0;
1738 if ( first_char == FAT_DIRENTRY_DELETED || !first_char )
1742 ++free_dir_entries_found;
1743 if ( free_dir_entries_found >= free_dir_entries_needed )
1752 dir_entry_offset = offset;
1754 free_dir_entries_found = 0;
1759 return dir_entry_offset;
1763 #if DOXYGEN || FAT_WRITE_SUPPORT 1785 if ( !fs || !dir_entry )
return 0;
1787 #if FAT_DATETIME_SUPPORT 1804 const char* name = dir_entry->
long_name;
1805 uint8_t name_len = strlen ( name );
1807 uint8_t lfn_entry_count = (name_len + 12) / 13;
1814 memset ( &buffer[0],
' ', 11 );
1815 char* name_ext = strrchr ( name,
'.' );
1816 if ( name_ext && *++name_ext )
1818 uint8_t name_ext_len = strlen ( name_ext );
1819 name_len -= name_ext_len + 1;
1821 if ( name_ext_len > 3 )
1828 memcpy ( &buffer[8], name_ext, name_ext_len );
1831 if ( name_len <= 8 )
1833 memcpy ( buffer, name, name_len );
1845 if ( name[0] ==
'.' && ((name[1] ==
'.' && name[2] ==
'\0') || name[1] ==
'\0') ) lfn_entry_count = 0;
1851 memcpy ( buffer, name, 8 );
1856 uint8_t num = dir_entry->
cluster & 0xff;
1858 buffer[6] = (num < 0xa0) ? ('0' + (num >> 4)) : (
'a' + (num >> 4));
1860 buffer[7] = (num < 0x0a) ? (
'0' + num) : (
'a' + num);
1865 if ( buffer[0] == FAT_DIRENTRY_DELETED ) buffer[0] = 0x05;
1868 memset ( &buffer[11], 0,
sizeof(buffer) - 11 );
1870 #if FAT_DATETIME_SUPPORT 1874 #if FAT_FAT32_SUPPORT 1875 write16( &buffer[0x14], (uint16_t ) (dir_entry->
cluster >> 16) );
1882 if ( !device_write ( offset + (uint16_t) lfn_entry_count * 32, buffer,
sizeof(buffer) ) )
1884 if(!device_write(offset, buffer,
sizeof(buffer)))
1893 for ( uint8_t lfn_entry = lfn_entry_count; lfn_entry > 0; --lfn_entry )
1895 memset ( buffer, 0xff,
sizeof(buffer) );
1898 const char* long_name_curr = name + (lfn_entry - 1) * 13;
1902 buffer[i++] = *long_name_curr;
1915 if ( !*long_name_curr++ )
break;
1919 buffer[0x00] = lfn_entry;
1920 if ( lfn_entry == lfn_entry_count ) buffer[0x00] |= FAT_DIRENTRY_LFNLAST;
1923 buffer[0x0b] = 0x0f;
1926 buffer[0x0d] = checksum;
1934 device_write ( offset, buffer,
sizeof(buffer) );
1936 offset +=
sizeof(buffer);
1944 #if DOXYGEN || FAT_WRITE_SUPPORT 1973 if ( !parent || !file || !file[0] || !dir_entry )
return 0;
1980 if ( strcmp ( file, dir_entry->
long_name ) == 0 )
1990 memset ( dir_entry, 0,
sizeof(*dir_entry) );
2003 #if DOXYGEN || FAT_WRITE_SUPPORT 2020 if ( !fs || !dir_entry )
return 0;
2024 if ( !dir_entry_offset )
return 0;
2031 if ( !fs->partition->
device_read ( dir_entry_offset, buffer,
sizeof(buffer) ) )
return 0;
2034 buffer[0] = FAT_DIRENTRY_DELETED;
2037 if ( !fs->partition->
device_write ( dir_entry_offset, buffer,
sizeof(buffer) ) )
return 0;
2040 if ( buffer[11] != 0x0f )
break;
2042 dir_entry_offset += 32;
2046 uint8_t first_char = FAT_DIRENTRY_DELETED;
2047 if(!fs->partition->
device_write(dir_entry_offset, &first_char, 1))
2058 #if DOXYGEN || FAT_WRITE_SUPPORT 2085 if ( !fs || !dir_entry || !parent_new || (file_new && !file_new[0]) )
return 0;
2086 if ( fs != parent_new->fs )
return 0;
2089 if ( !file_new ) file_new = dir_entry->
long_name;
2093 if ( !
fat_create_file ( parent_new, file_new, &dir_entry_new ) )
return 0;
2097 #if FAT_DATETIME_SUPPORT 2115 *dir_entry = dir_entry_new;
2120 #if DOXYGEN || FAT_WRITE_SUPPORT 2141 if ( !parent || !dir || !dir[0] || !dir_entry )
return 0;
2146 if ( strcmp ( dir, dir_entry->
long_name ) == 0 )
2157 if ( !dir_cluster )
return 0;
2162 memset ( dir_entry, 0,
sizeof(*dir_entry) );
2166 dir_entry->
entry_offset = fs->header.cluster_zero_offset + (offset_t) (dir_cluster - 2) * fs->header.cluster_size;
2168 dir_entry->
cluster = dir_cluster;
2187 dir_entry->
cluster = dir_cluster;
2243 #if DOXYGEN || FAT_DATETIME_SUPPORT 2255 if ( !dir_entry )
return;
2263 #if DOXYGEN || FAT_DATETIME_SUPPORT 2275 if ( !dir_entry )
return;
2283 #if DOXYGEN || (FAT_WRITE_SUPPORT && FAT_DATETIME_SUPPORT) 2295 if ( !dir_entry )
return;
2297 dir_entry->
modification_date = ((year - 1980) << 9) | ((uint16_t) month << 5) | ((uint16_t) day << 0);
2301 #if DOXYGEN || (FAT_WRITE_SUPPORT && FAT_DATETIME_SUPPORT) 2313 if ( !dir_entry )
return;
2315 dir_entry->
modification_time = ((uint16_t) hour << 11) | ((uint16_t) min << 5) | ((uint16_t) sec >> 1);
2328 if ( !fs )
return 0;
2330 #if FAT_FAT32_SUPPORT 2332 return (offset_t) (fs->header.fat_size / 4 - 2) * fs->header.cluster_size;
2335 return (offset_t) (fs->header.fat_size / 2 - 2) * fs->header.cluster_size;
2350 if ( !fs )
return 0;
2354 count_arg.cluster_count = 0;
2355 count_arg.buffer_size =
sizeof(fat);
2357 offset_t fat_offset = fs->header.fat_offset;
2358 uint32_t fat_size = fs->header.fat_size;
2359 while ( fat_size > 0 )
2361 uintptr_t length = UINTPTR_MAX - 1;
2362 if ( fat_size < length ) length = fat_size;
2370 &count_arg ) )
return 0;
2372 fat_offset += length;
2376 return (offset_t) count_arg.cluster_count * fs->header.cluster_size;
2386 uintptr_t buffer_size = count_arg->buffer_size;
2388 for ( uintptr_t i = 0; i < buffer_size; i += 2, buffer += 2 )
2390 uint16_t cluster =
read16( buffer );
2391 if ( cluster ==
HTOL16( FAT16_CLUSTER_FREE ) ) ++(count_arg->cluster_count);
2397 #if DOXYGEN || FAT_FAT32_SUPPORT 2405 uintptr_t buffer_size = count_arg->buffer_size;
2407 for ( uintptr_t i = 0; i < buffer_size; i += 4, buffer += 4 )
2409 uint32_t cluster =
read32( buffer );
2410 if ( cluster ==
HTOL32( FAT32_CLUSTER_FREE ) ) ++(count_arg->cluster_count);
2417 #if FAT_DATETIME_SUPPORT 2452 void get_datetime ( uint16_t* year, uint8_t* month, uint8_t* day, uint8_t* hour, uint8_t* min, uint8_t* sec )
2455 *year = now.year + 2000;
uint8_t(* device_write_t)(offset_t offset, const uint8_t *buffer, uintptr_t length)
device_read_t device_read
uint8_t(* device_read_t)(offset_t offset, uint8_t *buffer, uintptr_t length)
SD-Card Reader Bibliothek von Roland Riegel. Common SD-reader configuration used by all modules (lice...
uint8_t fat_move_file(struct fat_fs_struct *fs, struct fat_dir_entry_struct *dir_entry, struct fat_dir_struct *parent_new, const char *file_new)
struct fat_dir_struct * fat_open_dir(struct fat_fs_struct *fs, const struct fat_dir_entry_struct *dir_entry)
uint8_t fat_reset_dir(struct fat_dir_struct *dd)
Header, Definition der Konstanten und Commands für DS1388.
void fat_close_dir(struct fat_dir_struct *dd)
SD-Card Reader Bibliothek von Roland Riegel.
offset_t fat_get_fs_size(const struct fat_fs_struct *fs)
void DS1388_get_datetime(void)
Die Uhrzeit und das Datum werden ausgelesen.
static void fat_set_file_modification_date(struct fat_dir_entry_struct *dir_entry, uint16_t year, uint8_t month, uint8_t day)
uint8_t fat_read_dir(struct fat_dir_struct *dd, struct fat_dir_entry_struct *dir_entry)
static offset_t fat_find_offset_for_dir_entry(struct fat_fs_struct *fs, const struct fat_dir_struct *parent, const struct fat_dir_entry_struct *dir_entry)
uint16_t modification_time
static offset_t fat_cluster_offset(const struct fat_fs_struct *fs, cluster_t cluster_num)
device_read_interval_t device_read_interval
SD-Card Reader Bibliothek von Roland Riegel.
intptr_t fat_read_file(struct fat_file_struct *fd, uint8_t *buffer, uintptr_t buffer_len)
void write16(uint8_t *p, uint16_t i)
uint16_t modification_date
static void fat_set_file_modification_time(struct fat_dir_entry_struct *dir_entry, uint8_t hour, uint8_t min, uint8_t sec)
uint8_t fat_create_dir(struct fat_dir_struct *parent, const char *dir, struct fat_dir_entry_struct *dir_entry)
uint32_t read32(const uint8_t *p)
static cluster_t fat_append_clusters(struct fat_fs_struct *fs, cluster_t cluster_num, cluster_t count)
void write32(uint8_t *p, uint32_t i)
uint8_t fat_delete_file(struct fat_fs_struct *fs, struct fat_dir_entry_struct *dir_entry)
SD-Card Reader Bibliothek von Roland Riegel.
static uint8_t fat_dir_entry_read_callback(uint8_t *buffer, offset_t offset, void *p)
uint8_t fat_create_file(struct fat_dir_struct *parent, const char *file, struct fat_dir_entry_struct *dir_entry)
static uint8_t fat_free_clusters(struct fat_fs_struct *fs, cluster_t cluster_num)
static uint8_t fat_get_fs_free_16_callback(uint8_t *buffer, offset_t offset, void *p)
uint16_t read16(const uint8_t *p)
static uint8_t fat_terminate_clusters(struct fat_fs_struct *fs, cluster_t cluster_num)
#define PARTITION_TYPE_FAT32
static uint8_t fat_clear_cluster(const struct fat_fs_struct *fs, cluster_t cluster_num)
static uint8_t fat_get_fs_free_32_callback(uint8_t *buffer, offset_t offset, void *p)
void fat_close_file(struct fat_file_struct *fd)
#define PARTITION_TYPE_FAT16
void fat_close(struct fat_fs_struct *fs)
void get_datetime(uint16_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec)
This function is the link between the hardware RTC and the timekeeping function to the sd-reader code...
device_write_interval_t device_write_interval
uint8_t fat_get_dir_entry_of_path(struct fat_fs_struct *fs, const char *path, struct fat_dir_entry_struct *dir_entry)
static uint8_t fat_calc_83_checksum(const uint8_t *file_name_83)
intptr_t fat_write_file(struct fat_file_struct *fd, const uint8_t *buffer, uintptr_t buffer_len)
device_write_t device_write
struct fat_file_struct * fat_open_file(struct fat_fs_struct *fs, const struct fat_dir_entry_struct *dir_entry)
uint8_t fat_seek_file(struct fat_file_struct *fd, int32_t *offset, uint8_t whence)
struct fat_fs_struct * fat_open(struct partition_struct *partition)
static uint8_t fat_read_header(struct fat_fs_struct *fs)
void fat_get_file_modification_time(const struct fat_dir_entry_struct *dir_entry, uint8_t *hour, uint8_t *min, uint8_t *sec)
#define fat_get_datetime(year, month, day, hour, min, sec)
void fat_get_file_modification_date(const struct fat_dir_entry_struct *dir_entry, uint16_t *year, uint8_t *month, uint8_t *day)
#define FAT_WRITE_SUPPORT
static cluster_t fat_get_next_cluster(const struct fat_fs_struct *fs, cluster_t cluster_num)
static uint8_t fat_write_dir_entry(const struct fat_fs_struct *fs, struct fat_dir_entry_struct *dir_entry)
static uintptr_t fat_clear_cluster_callback(uint8_t *buffer, offset_t offset, void *p)
#define FAT_FAT32_SUPPORT
SD-Card Reader Bibliothek von Roland Riegel.
offset_t fat_get_fs_free(const struct fat_fs_struct *fs)
uint8_t fat_resize_file(struct fat_file_struct *fd, uint32_t size)