Hallo,
just in case this thread is still of interest. I was faced with the same problem, that i couldn't write larger files on the sd card.
I found mistakes in the
altera_up_sd_card_ avalon_intervace.c file of the driver.
1. the current_sector_in_cluster is calculated wrong after filling the 5th sector. Hence files greater than 5 sectors are not written properly.
2. Overwriting files didn't work either. Reason the whole function is post incremental, that means if you want to overwrite it the file size is one byte to big. I added a if-construct to decrement the active_files[file_handle].file_size_in_bytes.
The two modifications solved the problem for my application. To use it for your project you might need to adapt the code again. Here is the function in, which the alterations were made. Just copy and replace the original function in your file. The changes are also marked with comments.
bool alt_up_sd_card_write(short int file_handle, char byte_of_data)
/* Write a single character to a given file. Return true if successful, and false otherwise. */
{
bool result = false;
if ((file_handle >= 0) && (file_handle < MAX_FILES_OPENED))
{
if (active_files[file_handle].in_use)
{
int data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster +
active_files[file_handle].current_sector_in_cluster;
short int buffer_offset = active_files[file_handle].current_byte_position % boot_sector_data.sector_size_in_bytes;
if (active_files[file_handle].current_byte_position < active_files[file_handle].file_size_in_bytes)
{
if ((active_files[file_handle].current_byte_position > 0) && (buffer_offset == 0))
{
// Read in a new sector of data.
if (active_files[file_handle].current_sector_in_cluster == boot_sector_data.sectors_per_cluster - 1)
{
// Go to the next cluster.
unsigned short int next_cluster;
if (get_cluster_flag(active_files[file_handle].current_cluster_index, &next_cluster))
{
if (next_cluster < 0x0000fff8)
{
active_files[file_handle].current_cluster_index = next_cluster;
active_files[file_handle].current_sector_in_cluster = 0;
data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster +
active_files[file_handle].current_sector_in_cluster;
}
}
else
{
return false;
}
}
else
{
active_files[file_handle].current_sector_in_cluster = active_files[file_handle].current_sector_in_cluster + 1;
data_sector = data_sector + 1;
}
}
}
else
{
/* You are adding data to the end of the file, so increment its size and look for an additional data cluster if needed. */
if ((active_files[file_handle].current_byte_position > 0) && (buffer_offset == 0))
{
if (active_files[file_handle].current_sector_in_cluster == boot_sector_data.sectors_per_cluster - 1)
{
/* Find a new cluster if possible. */
unsigned int cluster_number;
if (find_first_empty_cluster(&cluster_number))
{
// mark clusters in both File Allocation Tables.
mark_cluster(active_files[file_handle].current_cluster_index, ((unsigned short int) (cluster_number & 0x0000ffff)), true);
mark_cluster(cluster_number, 0xffff, true);
mark_cluster(active_files[file_handle].current_cluster_index, ((unsigned short int) (cluster_number & 0x0000ffff)), false);
mark_cluster(cluster_number, 0xffff, false);
// Change cluster index and sector index to compute a new data sector.
active_files[file_handle].current_cluster_index = cluster_number;
active_files[file_handle].current_sector_in_cluster = 0;
}
else
{
return false;
}
}
else
{
/* Read the next sector in the cluster and modify it. We only need to change the data_sector value. The actual read happens a few lines below. */
//-----------------------Next line altered-----------------------------------
active_files[file_handle].current_sector_in_cluster = (active_files[file_handle].current_byte_position / boot_sector_data.sector_size_in_bytes) % boot_sector_data.sectors_per_cluster;
}
data_sector = boot_sector_data.data_sector_offset + (active_files[file_handle].current_cluster_index - 2)*boot_sector_data.sectors_per_cluster +
active_files[file_handle].current_sector_in_cluster;
}
}
// Reading a data sector into the buffer. Note that changes to the most recently modified sector will be saved before
// a new sector is read from the SD Card.
if (current_sector_index != data_sector + fat_partition_offset_in_512_byte_sectors)
{
if (!Read_Sector_Data(data_sector, fat_partition_offset_in_512_byte_sectors))
{
return false;
}
}
// Write a byte of data to the buffer.
IOWR_8DIRECT(buffer_memory, buffer_offset, byte_of_data);
active_files[file_handle].current_byte_position = active_files[file_handle].current_byte_position + 1;
// Modify the file record only when necessary.
if (active_files[file_handle].current_byte_position >= active_files[file_handle].file_size_in_bytes)
{
active_files[file_handle].file_size_in_bytes = active_files[file_handle].file_size_in_bytes + 1;
active_files[file_handle].modified = true;
}
//-------------------------------additions start------------------------------------
if ((active_files[file_handle].current_byte_position +1) == active_files[file_handle].file_size_in_bytes){
active_files[file_handle].file_size_in_bytes--;
}
//-------------------------------additions end------------------------------------
// Invaldiate the buffer to ensure that the buffer contents are written to the SD card whe nthe file is closed.
current_sector_modified = true;
result = true;
}
}
return result;
}