sdk例程:ddr3_fats移植 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki
说明
- 因为ddr3是memory mapped,读写非常简单,用memcpy即可,因此移植FATFS非常容易。
- 为了让容量计算正确,我们这里采用sector_size=512。这个也是FATFS的默认设置。
关键函数
diskio.c
#include "diskio.h"
#include "ff.h"
#include "xil_types.h"
#include "sleep.h"
#include "xil_printf.h"
#include "..\ACZ702_Lib\COMMON.h"
// #define SECTOR_SIZE 4096
// #define BLOCK_SIZE 4096
// #define NUM_SECTORS 1024
#define SECTOR_SIZE 512
#define BLOCK_SIZE 4096
#define NUM_SECTORS 8192
#define DDR_FATFS_BASE 0x11000000
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
/*****************************************************************************/
/**
*
* Gets the status of the disk.
* In case of SD, it checks whether card is present or not.
*
* @param pdrv - Drive number
*
* @return
* 0 Status ok
* STA_NOINIT Drive not initialized
* STA_NODISK No medium in the drive
* STA_PROTECT Write protected
*
* @note In case Card detect signal is not connected,
* this function will not be able to check if card is present.
*
******************************************************************************/
DSTATUS disk_status (
BYTE pdrv /* Drive number (0) */
)
{
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
/*****************************************************************************/
/**
*
* Initializes the drive.
* In case of SD, it initializes the host controller and the card.
* This function also selects additional settings such as bus width,
* speed and block size.
*
* @param pdrv - Drive number
*
* @return s - which contains an OR of the following information
* STA_NODISK Disk is not present
* STA_NOINIT Drive not initialized
* STA_PROTECT Drive is write protected
* 0 or only STA_PROTECT both indicate successful initialization.
*
* @note
*
******************************************************************************/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive number (0) */
)
{
xil_printf("init\n");
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
/*****************************************************************************/
/**
*
* Reads the drive
* In case of SD, it reads the SD card using ADMA2 in polled mode.
*
* @param pdrv - Drive number
* @param *buff - Pointer to the data buffer to store read data
* @param sector - Start sector number
* @param count - Sector count
*
* @return
* RES_OK Read successful
* STA_NOINIT Drive not initialized
* RES_ERROR Read not successful
*
* @note
*
******************************************************************************/
DRESULT disk_read (
BYTE pdrv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
UINT count /* Sector count (1..128) */
)
{
xil_printf("read: %d\n", sector);
u32 addr=DDR_FATFS_BASE+sector*SECTOR_SIZE;
u32 length=count*SECTOR_SIZE;
memcpy(buff, addr, length);
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive number (0) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res = RES_OK;
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = BLOCK_SIZE/SECTOR_SIZE;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = NUM_SECTORS;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
xil_printf("io_ctrl\n");
return res;
}
/******************************************************************************/
/**
*
* This function is User Provided Timer Function for FatFs module
*
* @return DWORD
*
* @note None
*
****************************************************************************/
DWORD get_fattime (void)
{
return ((DWORD)(2010U - 1980U) << 25U) /* Fixed to Jan. 1, 2010 */
| ((DWORD)1 << 21)
| ((DWORD)1 << 16)
| ((DWORD)0 << 11)
| ((DWORD)0 << 5)
| ((DWORD)0 >> 1);
}
/*****************************************************************************/
/**
*
* Reads the drive
* In case of SD, it reads the SD card using ADMA2 in polled mode.
*
* @param pdrv - Drive number
* @param *buff - Pointer to the data to be written
* @param sector - Sector address
* @param count - Sector count
*
* @return
* RES_OK Read successful
* STA_NOINIT Drive not initialized
* RES_ERROR Read not successful
*
* @note
*
******************************************************************************/
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
UINT count /* Number of sectors to write (1..128) */
)
{
xil_printf("write: %d\n", sector);
u32 addr=DDR_FATFS_BASE+sector*SECTOR_SIZE;
u32 length=count*SECTOR_SIZE;
memcpy(addr, buff, length);
return RES_OK;
}
ffconf.h
main.c
#include "ACZ702_Lib/COMMON.h"
#include "xil_cache.h"
#include "FATFS/ff.h"
rec_buff_t rec_buffer;
qspi_buff_t qspi_buffer;
#define FILE_NAME "ZDYZ.txt" //定义文件名
const char src_str[30] = "www.openedv.com"; //定义文本内容
//main函数
int main_fats()
{
int status,len;
char dest_str[30] = "";
status = sd_mount(); //挂载SD卡
if(status != XST_SUCCESS){
xil_printf("Failed to open SD card!\n");
return 0;
}
else
xil_printf("Success to open SD card!\n");
len = strlen(src_str); //计算字符串长度
//SD卡写数据
sd_write_data(FILE_NAME,(u32)src_str,len);
//SD卡读数据
sd_read_data(FILE_NAME,(u32)dest_str,len);
xil_printf("%s---%s\n", src_str, dest_str);
//比较写入的字符串和读出的字符串是否相等
if (strcmp(src_str, dest_str) == 0)
xil_printf("src_str is equal to dest_str,SD card test success!\n");
else
xil_printf("src_str is not equal to dest_str,SD card test failed!\n");
DWORD fre_clust, fre_sect, tot_sect;
/* Get volume information and free clusters of drive 1 */
FATFS *pfs=&fs;
f_getfree("0:", &fre_clust, &pfs);
/* Get total sectors and free sectors */
tot_sect = (fs.n_fatent - 2) * fs.csize;
fre_sect = fre_clust * fs.csize;
/* Print the free space (assuming 512 bytes/sector) */
printf("%10lu KiB total drive space.\n%10lu KiB available.\n", tot_sect / 2, fre_sect / 2);
return 0;
}
int main_uart_wr_to_qspi(void)
{
PS_UART_Init(&UartPs1,XPAR_PS7_UART_0_DEVICE_ID, XUARTPS_OPER_MODE_NORMAL, 115200);
QspiFlash_Init();
PS_UART_RX(&rec_buffer);
PS_UART_TX(&rec_buffer);
u32 err_cnt=0;
qspi_buffer.wr_length=rec_buffer.recv_length;
qspi_buffer.rd_length=rec_buffer.recv_length;
// qspi_buffer.wr_en=1;
// qspi_buffer.rd_en=1;
qspi_buffer.flash_start_addr= 0x400000;
W25QXX_Write(qspi_buffer.wr_buff, qspi_buffer.flash_start_addr, qspi_buffer.wr_length);
W25QXX_Read(qspi_buffer.rd_buff, qspi_buffer.flash_start_addr, qspi_buffer.rd_length);
for (int Count = 0; Count < qspi_buffer.rd_length; Count++) {
printf("%d: %x--%x\n", Count, qspi_buffer.wr_buff[Count], qspi_buffer.rd_buff[Count]);
if(qspi_buffer.wr_buff[Count]!=qspi_buffer.rd_buff[Count]){
err_cnt++;
}
}
xil_printf("Error_cnt=%d\r\n", err_cnt);
return 0;
}
int main_qspi_write_read_test(void)
{
QspiFlash_Init();
qspi_buffer.wr_length=2000;
qspi_buffer.rd_length=2000;
// qspi_buffer.wr_en=1;
// qspi_buffer.rd_en=1;
qspi_buffer.flash_start_addr=0;
for(int i=0; i<2000; i++){
qspi_buffer.wr_buff[i]=i*i;
qspi_buffer.rd_buff[i]=0;
}
W25QXX_Write(qspi_buffer.wr_buff, qspi_buffer.flash_start_addr, qspi_buffer.wr_length);
W25QXX_Read(qspi_buffer.rd_buff, qspi_buffer.flash_start_addr, qspi_buffer.rd_length);
for (int Count = 0; Count < qspi_buffer.rd_length; Count++) {
printf("%d: %x--%x\n", Count, qspi_buffer.wr_buff[Count], qspi_buffer.rd_buff[Count]);
}
return 0;
}
int main_uart_wr_to_qspi_fats(void)
{
PS_UART_Init(&UartPs1,XPAR_PS7_UART_0_DEVICE_ID, XUARTPS_OPER_MODE_NORMAL, 115200);
platform_init_fs();
PS_UART_RX(&rec_buffer);
u32 err_cnt=0;
memcpy(qspi_buffer.wr_buff, rec_buffer.rec_buff, rec_buffer.recv_length);
qspi_buffer.wr_length=rec_buffer.recv_length;
qspi_buffer.rd_length=rec_buffer.recv_length;
char file_name[30]="aa.bin";
//SD卡写数据
sd_write_data(file_name,(u32)qspi_buffer.wr_buff,qspi_buffer.wr_length);
//SD卡读数据
sd_read_data(file_name,(u32)qspi_buffer.rd_buff,qspi_buffer.rd_length);
for (int Count = 0; Count < qspi_buffer.rd_length; Count++) {
//printf("%d: %x--%x\n", Count, qspi_buffer.wr_buff[Count], qspi_buffer.rd_buff[Count]);
if(qspi_buffer.wr_buff[Count]!=qspi_buffer.rd_buff[Count]){
err_cnt++;
}
}
xil_printf("Error_cnt=%d\r\n", err_cnt);
return 0;
}
int run_demo()
{
//sd_mount();
demo_find_files();
demo_scan_files();
demo_list_dir();
demo_get_free();
return 0;
}
int main(void)
{
Xil_DCacheDisable();
//main_uart_wr_to_qspi();
xil_printf("hello\r\n");
main_fats();
//main_qspi_write_read_test();
//main_uart_wr_to_qspi_fats();
run_demo();
}
运行结果
hello
init
read: 0
read: 63
Success to open SD card!
read: 80
write: 80
read: 64
write: 64
read: 80
0
read: 64
0
15
write: 112
write: 64
read: 80
write: 80
io_ctrl
read: 112
15
www.openedv.com---www.openedv.com
src_str is equal to dest_str,SD card test success!
read: 64
read: 65
read: 66
read: 67
read: 68
read: 69
read: 70
read: 71
read: 72
read: 73
read: 74
read: 75
4040 KiB total drive space.
4039 KiB available.
init
read: 0
read: 63
read: 80
init
read: 0
read: 63
read: 80
15 ZDYZ.TXT
0 dirs, 1 files.
init
read: 0
read: 63
read: 80
//ZDYZ.TXT
init
read: 0
read: 63
read: 64
read: 65
read: 66
read: 67
read: 68
read: 69
read: 70
read: 71
read: 72
read: 73
read: 74
read: 75
4040 KiB total drive space.
4039 KiB available.