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

image image

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.