FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6359 Discussions

SD Card IP Core Limitations

Altera_Forum
Honored Contributor II
1,248 Views

Hello, 

 

I have used the Altera UP IP Core for the SD card controller. I was able to write a text file with a the character 'A'. The file was created and when the file is opened in the computer the character A is there. However, when the file reaches a size of 10KB plus minus, the file can no longer be viewed (ie. the file is corrupted). 

 

What could be wrong with this? Could the error be found in the IP core itself? 

 

Regards,
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
282 Views

Hello, 

 

I am using the Altera UP ip core for the SD card controller too. but i could not open a file successfully. even the fat 16 file system check is error, can you give me some advice, thanks in advance
0 Kudos
Altera_Forum
Honored Contributor II
282 Views

When you use the open function you can read data stored in it directly.

0 Kudos
Altera_Forum
Honored Contributor II
282 Views

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; 

}  

0 Kudos
Altera_Forum
Honored Contributor II
282 Views

I have the same UP SD card reading problem and I would like to know whether you find a solution for this problem or not. (1GB SD card formatted to FAT 16) Thanks in advance for any help you can provide.

0 Kudos
Reply