Index: fat16.c =================================================================== --- fat16.c (.../sd-reader_release_20060316) (Revision 106) +++ fat16.c (.../sd-reader_release_20060319) (Revision 106) @@ -139,6 +139,7 @@ struct fat16_fs_struct* fs; struct fat16_dir_entry_struct dir_entry; uint32_t pos; + uint16_t pos_cluster; }; struct fat16_dir_struct @@ -771,6 +772,7 @@ memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry)); fd->fs = fs; fd->pos = 0; + fd->pos_cluster = dir_entry->cluster; return fd; } @@ -813,31 +815,38 @@ return 0; uint16_t cluster_size = fd->fs->header.cluster_size; - uint16_t cluster_num = fd->dir_entry.cluster; + uint16_t cluster_num = fd->pos_cluster; uint16_t buffer_left = buffer_len; - uint16_t first_cluster_offset; + uint16_t first_cluster_offset = fd->pos % cluster_size; /* find cluster in which to start reading */ - if(cluster_num) + if(!cluster_num) { - uint32_t pos = fd->pos; - while(pos >= cluster_size) + cluster_num = fd->dir_entry.cluster; + + if(!cluster_num) { - pos -= cluster_size; - cluster_num = fat16_get_next_cluster(fd->fs, cluster_num); - if(!cluster_num) + if(!fd->pos) + return 0; + else return -1; } - first_cluster_offset = pos; + if(fd->pos) + { + uint32_t pos = fd->pos; + while(pos >= cluster_size) + { + pos -= cluster_size; + cluster_num = fat16_get_next_cluster(fd->fs, cluster_num); + if(!cluster_num) + return -1; + } + } } - else - { - return -1; - } /* read data */ - while(1) + do { /* calculate data size to copy from cluster */ uint32_t cluster_offset = fd->fs->header.cluster_zero_offset + @@ -855,17 +864,24 @@ buffer_left -= copy_length; fd->pos += copy_length; - /* check if we are done */ - if(buffer_left == 0) - break; - - /* we are on a cluster boundary, so get the next cluster */ - if((cluster_num = fat16_get_next_cluster(fd->fs, cluster_num))) - first_cluster_offset = 0; - else - return buffer_len - buffer_left; - } + if(first_cluster_offset + copy_length >= cluster_size) + { + /* we are on a cluster boundary, so get the next cluster */ + if((cluster_num = fat16_get_next_cluster(fd->fs, cluster_num))) + { + first_cluster_offset = 0; + } + else + { + fd->pos_cluster = 0; + return buffer_len - buffer_left; + } + } + fd->pos_cluster = cluster_num; + + } while(buffer_left > 0); /* check if we are done */ + return buffer_len; } @@ -891,36 +907,51 @@ return -1; uint16_t cluster_size = fd->fs->header.cluster_size; - uint16_t cluster_num = fd->dir_entry.cluster; + uint16_t cluster_num = fd->pos_cluster; uint16_t buffer_left = buffer_len; - uint16_t first_cluster_offset = 0; + uint16_t first_cluster_offset = fd->pos % cluster_size; /* find cluster in which to start writing */ - if(cluster_num) + if(!cluster_num) { - uint32_t pos = fd->pos; - while(pos >= cluster_size) + cluster_num = fd->dir_entry.cluster; + + if(!cluster_num) { - pos -= cluster_size; - cluster_num = fat16_get_next_cluster(fd->fs, cluster_num); - if(!cluster_num && pos == 0) - /* the file exactly ends on a cluster boundary, and we append to it */ - cluster_num = fat16_append_cluster(fd->fs, cluster_num); - if(!cluster_num) + if(!fd->pos) + { + /* empty file */ + fd->dir_entry.cluster = cluster_num = fat16_append_cluster(fd->fs, 0); + if(!cluster_num) + return -1; + } + else + { return -1; + } } - first_cluster_offset = pos; + if(fd->pos) + { + uint32_t pos = fd->pos; + uint16_t cluster_num_next; + while(pos >= cluster_size) + { + pos -= cluster_size; + cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num); + if(!cluster_num_next && pos == 0) + /* the file exactly ends on a cluster boundary, and we append to it */ + cluster_num_next = fat16_append_cluster(fd->fs, cluster_num); + if(!cluster_num_next) + return -1; + + cluster_num = cluster_num_next; + } + } } - else - { - fd->dir_entry.cluster = cluster_num = fat16_append_cluster(fd->fs, 0); - if(!cluster_num) - return -1; - } /* write data */ - while(1) + do { /* calculate data size to write to cluster */ uint32_t cluster_offset = fd->fs->header.cluster_zero_offset + @@ -938,23 +969,27 @@ buffer_left -= write_length; fd->pos += write_length; - /* check if we are done */ - if(buffer_left == 0) - break; - - /* we are on a cluster boundary, so get the next cluster */ - uint16_t cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num); - if(!cluster_num_next) + if(first_cluster_offset + write_length >= cluster_size) { - cluster_num_next = fat16_append_cluster(fd->fs, cluster_num); + /* we are on a cluster boundary, so get the next cluster */ + uint16_t cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num); + if(!cluster_num_next && buffer_left > 0) + /* we reached the last cluster, append a new one */ + cluster_num_next = fat16_append_cluster(fd->fs, cluster_num); if(!cluster_num_next) + { + fd->pos_cluster = 0; break; + } + + cluster_num = cluster_num_next; + first_cluster_offset = 0; } - cluster_num = cluster_num_next; - - first_cluster_offset = 0; - } + fd->pos_cluster = cluster_num; + + } while(buffer_left > 0); /* check if we are done */ + /* update directory entry */ if(fd->pos > fd->dir_entry.file_size) { @@ -1032,6 +1067,8 @@ return 0; fd->pos = new_pos; + fd->pos_cluster = 0; + *offset = new_pos; return 1; } @@ -1133,6 +1170,13 @@ cluster_num = cluster_num_next; } } + + /* correct file position */ + if(size < fd->pos) + { + fd->pos = size; + fd->pos_cluster = 0; + } } return 1; Index: main.c =================================================================== --- main.c (.../sd-reader_release_20060316) (Revision 106) +++ main.c (.../sd-reader_release_20060319) (Revision 106) @@ -69,17 +69,17 @@ * *