Search |
 |
|
 |
| Author |
Message |
|
|
Posted: Mar 28, 2009 - 07:32 PM |
|

Joined: Jul 18, 2005
Posts: 803
|
|
| ok, so you use your own driver for your own card, not a general driver for every SD card, right? |
|
|
| |
|
|
|
|
|
Posted: Mar 28, 2009 - 08:44 PM |
|

Joined: Dec 31, 2008
Posts: 521
Location: Langgoens, Germany
|
|
| Yes it's our own driver but it should work with all kind of cards. We have five different tested from 16MB up to 2GB. |
|
|
| |
|
|
|
|
|
Posted: Mar 29, 2009 - 09:23 AM |
|

Joined: Jul 18, 2005
Posts: 803
|
|
aha!
hehe, do you want to share your driver with us??? |
|
|
| |
|
|
|
|
|
Posted: May 24, 2010 - 05:58 AM |
|

Joined: Jul 13, 2009
Posts: 3
|
|
I finally improved the SD card speed from 250 KB/s to
2.5MB/s. What I did is to change the sd_mmc_mci_mem.c for the sd_mmc_mci_ram_2_mem_0 as following:
Ctrl_status sd_mmc_mci_ram_2_mem_0(U32 addr, const void *ram)
{
// return sd_mmc_mci_dma_ram_2_mem(0, addr, ram);
return sd_mmc_mci_dma_multiple_ram_2_mem(0, addr,ram, ;
}
and change ram_2_mem section in file.c as following:
// Directly data tranfert from buffer to memory
while( 0 != fs_g_seg.u32_size_or_pos )
{
if( CTRL_GOOD != ram_2_memory( fs_g_nav.u8_lun , fs_g_seg.u32_addr, buffer))
{
fs_g_status = FS_ERR_HW;
return u16_nb_write;
}
fs_g_seg.u32_size_or_pos -= 8;// 8;
fs_g_seg.u32_addr++;
buffer += FS_512B * 8;// * 8;
}
// Translate from sector unit to byte unit
u16_nb_write_tmp *= FS_512B;
Basically, the idea is to use DMA write for SD card with 8 sectors each write. With this change, the speed is 10 times higher. |
|
|
| |
|
|
|
|
|
Posted: May 25, 2010 - 05:44 AM |
|

Joined: Jul 13, 2009
Posts: 3
|
|
| I tried more to improve the SD write speed. In theory, you can use write_file() to pre-allocate the file so that the buffer can be transfered to SD using DMA without accessing FAT. But it is not always working especially when you have a large size fiel (eg. 20M byte) or these are already many sectors used in SD card. One way to do it is to use file_write_buf() to pre-allocate all the cluster for the file WITHOUT writing to SD by remove ram_2_mem() line. After the cluster list is established, the file can be writing to SD card at high speed. I tried use 16 sector size DMA to SD card, it takes 4 seconds to write a 20MB file which is 5MByte/s. |
|
|
| |
|
|
|
|
|
Posted: Jun 15, 2010 - 05:48 PM |
|

Joined: Jul 13, 2009
Posts: 3
|
|
One important point to remember that the buffer in the memory which will be written to the SD card needs to be aligned with /4 address which meaning it can be divided by 4 so that it starts at a new 32-bit memory address of MCU. Otherwise, it won't be written in page mode.
I created a function in file.c based on file_write_buf() standard function which is alway in the same file. This function will do multi-sector DMA transfer. Use it to write to SD card. I can get nearly 5MByte/second with SCandisk Ultra III.
//! This function transfer a buffer to a file at the current file position
//!
//! @param buffer data buffer
//! @param u16_buf_size data size
//!
//! @return number of byte write
//! @return 0, in case of error
//!
U16 file_write_buf_multi_dma( U8 _MEM_TYPE_SLOW_ *buffer , U16 u16_buf_size )
{
_MEM_TYPE_FAST_ U16 u16_nb_write_tmp;
_MEM_TYPE_FAST_ U16 u16_nb_write;
_MEM_TYPE_FAST_ U16 u16_pos_in_sector;
if( !fat_check_mount_select_open())
return FALSE;
if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode))
{
fs_g_status = FS_ERR_READ_ONLY;
return FALSE;
}
u16_nb_write = 0;
while( 0 != u16_buf_size )
{
// The file data sector can been directly transfer from buffer to memory (don't use internal cache)
u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B;
if( (0== u16_pos_in_sector)
&& (FS_512B <= u16_buf_size)
#if (defined __GNUC__) && (defined __AVR32__) || (defined __ICCAVR32__)
&& (Test_align((U32)buffer, sizeof(U32)))
#endif
)
{
u16_nb_write_tmp = u16_buf_size / FS_512B; // read a modulo sector size
// Get and eventually alloc the following sector segment of file
if( !fat_write_file( FS_CLUST_ACT_SEG , u16_nb_write_tmp ))
return FALSE;
// Truncate the segment found if more larger than asked size
if( u16_nb_write_tmp < fs_g_seg.u32_size_or_pos)
{
fs_g_seg.u32_size_or_pos = u16_nb_write_tmp;
}else{
u16_nb_write_tmp = fs_g_seg.u32_size_or_pos;
}
// Directly data tranfert from buffer to memory
if( CTRL_GOOD != sd_mmc_mci_dma_multiple_ram_2_mem(fs_g_nav.u8_lun , fs_g_seg.u32_addr, buffer, fs_g_seg.u32_size_or_pos))
{
fs_g_status = FS_ERR_HW;
return u16_nb_write;
}
fs_g_seg.u32_addr += fs_g_seg.u32_size_or_pos;
buffer += FS_512B * fs_g_seg.u32_size_or_pos;
fs_g_seg.u32_size_or_pos = 0;
// Translate from sector unit to byte unit
u16_nb_write_tmp *= FS_512B;
}
else
{
// The file data can't been directly transfer from buffer to memory, the internal cache must be used
// Tranfer and eventually alloc a data sector from internal cache to memory
if((fs_g_nav_entry.u32_pos_in_file == fs_g_nav_entry.u32_size)
&& (0==u16_pos_in_sector) )
{
// Eventually alloc one new sector for the file
if( !fat_write_file( FS_CLUST_ACT_SEG , 1 ))
return FALSE;
// Update the cache
fs_gu32_addrsector = fs_g_seg.u32_addr;
if( !fat_cache_read_sector( FALSE )) // The memory is not readed because it is a new sector
return FALSE;
}else{
// The sector must existed then alloc no necessary
if( !fat_write_file( FS_CLUST_ACT_ONE , 1 ))
return FALSE;
}
// Flag internal cache modified
fat_cache_mark_sector_as_dirty();
// Compute the number of data to transfer
u16_nb_write_tmp = FS_512B - u16_pos_in_sector; // The number is limited at sector size
if( u16_nb_write_tmp > u16_buf_size )
u16_nb_write_tmp = u16_buf_size;
// Tranfer data from buffer to internal cache
memcpy_ram2ram( &fs_g_sector[ u16_pos_in_sector ], buffer , u16_nb_write_tmp );
buffer += u16_nb_write_tmp;
}
// Update positions
fs_g_nav_entry.u32_pos_in_file+= u16_nb_write_tmp;
u16_nb_write += u16_nb_write_tmp;
u16_buf_size -= u16_nb_write_tmp;
// Update file size
if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size )
{
fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file;
}
}
return u16_nb_write; // All buffer is writed
} |
|
|
| |
|
|
|
|
|
|
|
|