Rev 396 | Rev 427 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 396 | Rev 407 | ||
---|---|---|---|
Line 60... | Line 60... | ||
60 | #include "fat16.h" |
60 | #include "fat16.h" |
61 | #include "sdc.h" |
61 | #include "sdc.h" |
62 | #include "uart1.h" |
62 | #include "uart1.h" |
63 | #include "main.h" |
63 | #include "main.h" |
64 | #include "logging.h" |
64 | #include "logging.h" |
65 | #include "debug.h" |
- | |
Line 66... | Line 65... | ||
66 | 65 | ||
67 | 66 | ||
68 | //________________________________________________________________________________________________________________________________________ |
67 | //________________________________________________________________________________________________________________________________________ |
Line 585... | Line 584... | ||
585 | if(SD_WatchDog > 2000) SD_WatchDog = 2000; |
584 | if(SD_WatchDog > 2000) SD_WatchDog = 2000; |
586 | SD_LoggingError = 100; |
585 | SD_LoggingError = 100; |
587 | return(returnvalue); |
586 | return(returnvalue); |
588 | } |
587 | } |
Line 589... | Line -... | ||
589 | - | ||
590 | 588 | ||
591 | /****************************************************************************************************************************************/ |
589 | /****************************************************************************************************************************************/ |
592 | /* Function: Fat16_Init(void); */ |
590 | /* Function: Fat16_Init(void); */ |
593 | /* */ |
591 | /* */ |
594 | /* Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdir */ |
592 | /* Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdir */ |
Line 904... | Line 902... | ||
904 | retvalue = 0; |
902 | retvalue = 0; |
905 | } |
903 | } |
906 | return(retvalue); |
904 | return(retvalue); |
907 | } |
905 | } |
Line -... | Line 906... | ||
- | 906 | ||
908 | 907 | ||
909 | /****************************************************************************************************************************************/ |
908 | /****************************************************************************************************************************************/ |
910 | /* Function: u16 DeleteClusterChain(File *file); */ |
909 | /* Function: u16 DeleteClusterChain(File *file); */ |
911 | /* */ |
910 | /* */ |
912 | /* Description: This function trances along a cluster chain in the fat and frees all clusters visited. */ |
911 | /* Description: This function trances along a cluster chain in the fat and frees all clusters visited. */ |
Line 979... | Line 978... | ||
979 | /* */ |
978 | /* */ |
980 | /* Description: This function looks in the fat to find the next free cluster and appends it to the file. */ |
979 | /* Description: This function looks in the fat to find the next free cluster and appends it to the file. */ |
981 | /* */ |
980 | /* */ |
982 | /* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended. */ |
981 | /* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended. */ |
983 | /****************************************************************************************************************************************/ |
982 | /****************************************************************************************************************************************/ |
- | 983 | ||
984 | u16 AppendCluster(File_t *file) |
984 | u16 AppendCluster(File_t *file) |
985 | { |
985 | { |
986 | u16 last_cluster, new_cluster = CLUSTER_UNDEFINED; |
986 | u16 last_cluster, new_cluster = CLUSTER_UNDEFINED; |
987 | u32 fat_byte_offset, sector, byte; |
987 | u32 fat_byte_offset, sector, byte; |
988 | Fat16Entry_t * fat; |
988 | Fat16Entry_t * fat; |
Line 989... | Line -... | ||
989 | - | ||
990 | 989 | ||
Line 991... | Line 990... | ||
991 | if((!Partition.IsValid) || (file == NULL)) return(new_cluster); |
990 | if((!Partition.IsValid) || (file == NULL)) return(new_cluster); |
992 | 991 | ||
993 | new_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk. |
992 | new_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk. |
994 | if(new_cluster != CLUSTER_UNDEFINED) |
- | |
995 | { // A free cluster was found and can be added to the end of the file. |
- | |
996 | // is there at least one cluster appended to the file? |
- | |
997 | if(file->FirstSectorOfLastCluster == CLUSTER_UNDEFINED) |
993 | if(new_cluster != CLUSTER_UNDEFINED) |
998 | { |
- | |
999 | fseek_(file, 0, SEEK_END); // jump to the end of the file |
- | |
1000 | // remember the first sector of the last cluster |
994 | { // A free cluster was found and can be added to the end of the file. |
1001 | file->FirstSectorOfLastCluster = file->FirstSectorOfCurrCluster; |
- | |
1002 | last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster); // determine current file cluster |
- | |
1003 | } |
- | |
1004 | else |
- | |
1005 | { |
- | |
1006 | last_cluster = SectorToFat16Cluster(file->FirstSectorOfLastCluster); // determine current file cluster |
- | |
1007 | } |
995 | fseek_(file, 0, SEEK_END); // jump to the end of the file |
1008 | 996 | last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster); // determine current file cluster |
|
1009 | if(last_cluster != CLUSTER_UNDEFINED) |
997 | if(last_cluster != CLUSTER_UNDEFINED) |
1010 | { |
998 | { |
1011 | // update FAT entry of last cluster |
999 | // update FAT entry of last cluster |
Line 1027... | Line 1015... | ||
1027 | if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache)) // save the modified sector to the FAT. |
1015 | if(SD_SUCCESS != SDC_PutSector(file->SectorInCache, file->Cache)) // save the modified sector to the FAT. |
1028 | { |
1016 | { |
1029 | Fat16_Deinit(); |
1017 | Fat16_Deinit(); |
1030 | return(0); |
1018 | return(0); |
1031 | } |
1019 | } |
1032 | // now the new cluster appended to the fat is the last cluster |
- | |
1033 | file->FirstSectorOfLastCluster = Fat16ClusterToSector(new_cluster); |
- | |
1034 | } |
1020 | } |
1035 | else // last cluster of the file is undefined |
1021 | else // last cluster of the file is undefined |
1036 | { // then the new cluster must be the first one of the file |
1022 | { // then the new cluster must be the first one of the file |
1037 | // and its cluster number must be set in the direntry |
1023 | // and its cluster number must be set in the direntry |
1038 | DirEntry_t * dir; |
1024 | DirEntry_t * dir; |
Line 1057... | Line 1043... | ||
1057 | Fat16_Deinit(); |
1043 | Fat16_Deinit(); |
1058 | return(CLUSTER_UNDEFINED); |
1044 | return(CLUSTER_UNDEFINED); |
1059 | } |
1045 | } |
1060 | // update file info |
1046 | // update file info |
1061 | file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster); |
1047 | file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster); |
1062 | file->FirstSectorOfLastCluster = file->FirstSectorOfFirstCluster; |
- | |
1063 | file->Size = 0; |
1048 | file->Size = 0; |
1064 | file->Position = 0; |
1049 | file->Position = 0; |
1065 | } |
1050 | } |
1066 | // update file pointes |
1051 | // update file pointes |
1067 | file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster); |
1052 | file->FirstSectorOfCurrCluster = Fat16ClusterToSector(new_cluster); |
Line 2148... | Line 2133... | ||
2148 | u8 readpointer = 0; |
2133 | u8 readpointer = 0; |
2149 | u8 writepointer = 0; |
2134 | u8 writepointer = 0; |
2150 | u8 retvalue = 0; |
2135 | u8 retvalue = 0; |
2151 | DirEntry_t *DirectoryEntry; |
2136 | DirEntry_t *DirectoryEntry; |
2152 | File_t file; |
2137 | File_t file; |
2153 | SD_Result_t res=0; |
- | |
Line 2154... | Line 2138... | ||
2154 | 2138 | ||
2155 | file.FirstSectorOfCurrCluster = findelement->fp.FirstSectorOfCurrCluster; |
2139 | file.FirstSectorOfCurrCluster = findelement->fp.FirstSectorOfCurrCluster; |
2156 | file.SectorOfCurrCluster = findelement->fp.SectorOfCurrCluster; |
2140 | file.SectorOfCurrCluster = findelement->fp.SectorOfCurrCluster; |
Line 2167... | Line 2151... | ||
2167 | max_dir_sector = Partition.SectorsPerCluster; // limit max secters before next cluster |
2151 | max_dir_sector = Partition.SectorsPerCluster; // limit max secters before next cluster |
2168 | } |
2152 | } |
Line 2169... | Line 2153... | ||
2169 | 2153 | ||
2170 | do |
2154 | do |
2171 | { // search the next 16 rootentries in this sector of the roordirectory. |
2155 | { // search the next 16 rootentries in this sector of the roordirectory. |
2172 | res = SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache); // Read the Rootdirectory. |
- | |
2173 | if(res != SD_SUCCESS) |
2156 | if(SD_SUCCESS != SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache)); // Read the Rootdirectory. |
2174 | { |
2157 | { |
2175 | Fat16_Deinit(); |
2158 | Fat16_Deinit(); |
2176 | return(0); |
2159 | return(0); |
Line 2476... | Line 2459... | ||
2476 | /* Description: This function changed the current working directory to the directory specified by the filepath */ |
2459 | /* Description: This function changed the current working directory to the directory specified by the filepath */ |
2477 | /* by function findfirst() */ |
2460 | /* by function findfirst() */ |
2478 | /* */ |
2461 | /* */ |
2479 | /* Returnvalue: */ |
2462 | /* Returnvalue: */ |
2480 | /********************************************************************************************************************************************/ |
2463 | /********************************************************************************************************************************************/ |
- | 2464 | /* |
|
- | 2465 | #define ATTR_NONE 0x00 // normal file |
|
- | 2466 | #define ATTR_READONLY 0x01 // file is readonly |
|
- | 2467 | #define ATTR_HIDDEN 0x02 // file is hidden |
|
- | 2468 | #define ATTR_SYSTEM 0x04 // file is a system file |
|
- | 2469 | #define ATTR_VOLUMELABEL 0x08 // entry is a volume label |
|
- | 2470 | #define ATTR_LONG_FILENAME 0x0F // this is a long filename entry |
|
- | 2471 | #define ATTR_SUBDIRECTORY 0x10 // entry is a directory name |
|
- | 2472 | #define ATTR_ARCHIVE 0x20 // file is new or modified |
|
- | 2473 | */ |
|
Line 2481... | Line 2474... | ||
2481 | 2474 | ||
2482 | u8 chdir_(s8 *path) |
2475 | u8 chdir_(s8 *path) |
2483 | { |
2476 | { |
2484 | u8 retvalue = 0; // the value returned by this function |
2477 | u8 retvalue = 0; // the value returned by this function |
Line 2497... | Line 2490... | ||
2497 | while(*cptr != 0 ) |
2490 | while(*cptr != 0 ) |
2498 | { |
2491 | { |
2499 | if(*cptr == '\\') *cptr = '/'; |
2492 | if(*cptr == '\\') *cptr = '/'; |
2500 | cptr++; |
2493 | cptr++; |
2501 | } |
2494 | } |
2502 | // Debug("1"); |
- | |
2503 | /* lets remember the actual path */ |
2495 | /* lets remember the actual path */ |
2504 | strcpy(tp, Partition.PathToCwd); |
2496 | strcpy(tp, Partition.PathToCwd); |
2505 | cwdt = Partition.CurrentWorkingDirectory; |
2497 | cwdt = Partition.CurrentWorkingDirectory; |
2506 | /* how many subdirectories are there within the path? */ |
2498 | /* how many subdirectories are there within the path? */ |
2507 | dircount = GetDirCount(path); |
2499 | dircount = GetDirCount(path); |
Line 2511... | Line 2503... | ||
2511 | strcpy(Partition.PathToCwd, "/"); |
2503 | strcpy(Partition.PathToCwd, "/"); |
2512 | Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector; |
2504 | Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector; |
2513 | /* if there is no other pathinformation we only switch to the rootdirectory. So theres nothing left todo.*/ |
2505 | /* if there is no other pathinformation we only switch to the rootdirectory. So theres nothing left todo.*/ |
2514 | if(!dircount) return(1); |
2506 | if(!dircount) return(1); |
2515 | } |
2507 | } |
2516 | // Debug("2"); |
- | |
2517 | /* now we parse through all the subdirectories within the path */ |
2508 | /* now we parse through all the subdirectories within the path */ |
2518 | do |
2509 | do |
2519 | { |
2510 | { |
2520 | /* until all the subdirectories within the path have been processed */ |
2511 | /* until all the subdirectories within the path have been processed */ |
2521 | if(dircount) dircount--; |
2512 | if(dircount) dircount--; |
Line 2530... | Line 2521... | ||
2530 | else if(cache[0] == '.') return(1); |
2521 | else if(cache[0] == '.') return(1); |
2531 | /* otherwise we append the name of the directory we are changing in to the path */ |
2522 | /* otherwise we append the name of the directory we are changing in to the path */ |
2532 | else AppendDirToPath(cache); |
2523 | else AppendDirToPath(cache); |
2533 | /* The startcluster within an directoryentry specifies the position within the fat where the file or directory starts */ |
2524 | /* The startcluster within an directoryentry specifies the position within the fat where the file or directory starts */ |
2534 | ultemp = (u32) fe.fp.FirstSectorOfFirstCluster; |
2525 | ultemp = (u32) fe.fp.FirstSectorOfFirstCluster; |
2535 | /* do we have to change into the rootdirectory? */ |
- | |
2536 | if(ultemp) |
- | |
2537 | { |
- | |
2538 | /* the first 2 entries are reserved for '.' and '..' */ |
2526 | /* the first 2 entries are reserved for '.' and '..' */ |
2539 | ultemp -= 2; |
2527 | ultemp -= 2; |
2540 | /* now we have to transform the position within the fat into the corrosponding sectoraddress relative to the beginning of the datasection of the active partition*/ |
2528 | /* now we have to transform the position within the fat into the corrosponding sectoraddress relative to the beginning of the datasection of the active partition*/ |
2541 | ultemp *= Partition.SectorsPerCluster; |
2529 | ultemp *= Partition.SectorsPerCluster; |
2542 | /* at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition */ |
2530 | /* at least we make the sectoraddress absolute by adding the relative address to the beginning of the datasection of the active partition */ |
2543 | ultemp += Partition.FirstDataSector; |
2531 | ultemp += Partition.FirstDataSector; |
2544 | /* the cwd now points to the specified directory */ |
2532 | /* the cwd now points to the specified directory */ |
2545 | Partition.CurrentWorkingDirectory = ultemp; |
2533 | Partition.CurrentWorkingDirectory = ultemp; |
2546 | /* we found the folder specified by the foldername */ |
2534 | /* we found the folder specified by the foldername */ |
2547 | retvalue = 1; |
- | |
2548 | } |
- | |
2549 | else |
- | |
2550 | { |
- | |
2551 | /* the cwd now points to the rootdirectory */ |
- | |
2552 | Partition.CurrentWorkingDirectory = Partition.FirstRootDirSector; |
- | |
2553 | /* changed into the rootdirectory succesfully */ |
- | |
2554 | retvalue = 1; |
2535 | retvalue = 1; |
2555 | } |
- | |
2556 | } |
2536 | } |
2557 | } |
2537 | } |
2558 | while(dircount && retvalue ); /* do this until all subdirectories have been found or a subdirectory is missing */ |
2538 | /* do this until all subdirectories have been found or a subdirectory is missing */ |
2559 | // Debug("3"); |
2539 | while(dircount && retvalue ); |
Line 2560... | Line 2540... | ||
2560 | 2540 | ||
2561 | /* if we could not change to the specified directory we restore the actual path */ |
2541 | /* if we could not change to the specified directory we restore the actual path */ |
2562 | if(!retvalue) |
2542 | if(!retvalue) |
2563 | { |
2543 | { |
2564 | Partition.CurrentWorkingDirectory = cwdt; |
2544 | Partition.CurrentWorkingDirectory = cwdt; |
2565 | strcpy(Partition.PathToCwd, tp); |
2545 | strcpy(Partition.PathToCwd, tp); |
2566 | } |
2546 | } |
2567 | return(retvalue); |
2547 | return(retvalue); |
2568 | } |
- | |
2569 | - | ||
2570 | - | ||
2571 | - | ||
2572 | /********************************************************************************************************************************************/ |
- | |
2573 | /* Function: void DeleteDirectoryEntry(Find *item) */ |
- | |
2574 | /* Description: This function deletes the directoryentry of the file to be deleted from the filesystem */ |
- | |
2575 | /* */ |
- | |
2576 | /* */ |
- | |
2577 | /* Returnvalue: none */ |
- | |
2578 | /********************************************************************************************************************************************/ |
- | |
2579 | - | ||
2580 | void DeleteDirectoryEntry(Find_t *fe) |
- | |
2581 | { |
- | |
2582 | DirEntry_t *DirectoryEntry = NULL; |
- | |
2583 | - | ||
2584 | /* read the sector containint the directoryentry of the file to be deleted */ |
- | |
2585 | SDC_GetSector((u32) fe->fp.DirectorySector,fe->fp.Cache); |
- | |
2586 | /* get access to the elements of the directoryentry */ |
- | |
2587 | DirectoryEntry = (DirEntry_t *)fe->fp.Cache; |
- | |
2588 | /* delete the directoryentry */ |
- | |
2589 | DirectoryEntry[fe->fp.DirectoryIndex].Attribute = 0; |
- | |
2590 | DirectoryEntry[fe->fp.DirectoryIndex].Name[0] = 0xE5; |
- | |
2591 | DirectoryEntry[fe->fp.DirectoryIndex].Size = 0; |
- | |
2592 | /* the file has been deleted from the directory, save the modified sector back to the filesystem */ |
- | |
2593 | SDC_PutSector((u32) fe->fp.DirectorySector,fe->fp.Cache); |
- | |
2594 | } |
- | |
2595 | - | ||
2596 | - | ||
2597 | - | ||
2598 | /********************************************************************************************************************************************/ |
- | |
2599 | /* Function: fdelete_(s8* filename); */ |
- | |
2600 | /* */ |
- | |
2601 | /* Description: This function deletes the file with the specified filename from the filesystem */ |
- | |
2602 | /* */ |
- | |
2603 | /* */ |
- | |
2604 | /* Returnvalue: 1 : specified file deleted succesfully 0: specified file not found */ |
- | |
2605 | /********************************************************************************************************************************************/ |
- | |
2606 | - | ||
2607 | u8 fdelete_(s8 *fname) |
- | |
2608 | { |
- | |
2609 | u8 retvalue = 0; |
- | |
2610 | Find_t fe; |
- | |
2611 | - | ||
2612 | /* search for the specified item */ |
- | |
2613 | retvalue = (u8) findfirst_(fname, 0xff, &fe); |
- | |
2614 | /* if the item was found */ |
- | |
2615 | if(retvalue) |
- | |
2616 | { |
- | |
2617 | /* is the file marked as readonly? */ |
- | |
2618 | if(0)//(fe.fp.Attribute & ATTR_READONLY) == ATTR_READONLY) |
- | |
2619 | { |
- | |
2620 | return(0); |
- | |
2621 | } |
- | |
2622 | /* file is not marked as readonly */ |
- | |
2623 | else |
- | |
2624 | { |
- | |
2625 | /* delete the file from the filesystem */ |
- | |
2626 | DeleteClusterChain(fe.fp.FirstSectorOfFirstCluster); |
- | |
2627 | /* delete the directoryentry of the file */ |
- | |
2628 | DeleteDirectoryEntry(&fe); |
- | |
2629 | } |
- | |
2630 | } |
- | |
2631 | - | ||
2632 | return(retvalue); |
- | |
2633 | } |
- | |
2634 | - | ||
2635 | - | ||
2636 | - |