复旦微用AXIDMA接收原始图像

news/2025/2/12 0:58:59/

参考SD卡移植博客,,移植SD卡相应代码
AXIDMA部分Demo下的bsp包整个pl搬到相应位置,添加相应文件

在这里插入图片描述


#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include "fmsh_common.h"
#include "ps_init.h"
#include "fmsh_print.h"#include "fmsh_ps_parameters.h"
#include "fmsh_gic.h"
#include "fmsh_gic_hw.h"
#include "fmsh_dmac_lib.h"
#include "cache.h"/* SD卡包含库 */
#include "diskio.h"
#include "ff.h"/* axidma包汉库 */
#include "xaxidma.h"
#include "xparameters.h"
#include "fmsh_parameters.h"/* Emio包含库 */
#include "fmsh_gpio_public.h"/* xil_printf should be added the debug file of the pl/inlcude/ path * the compiler's include path can be in the project's options!!!*/
#define xil_printf 					fmsh_print
#define SD_SAVE#ifdef XPAR_UARTNS550_0_BASEADDR
#include "xuartns550_l.h"       /* to use uartns550 */
#endif/************************** Constant Definitions *****************************//** Device hardware build related constants.*/#define DMA_DEV_ID					XPAR_AXIDMA_0_DEVICE_ID/* Note FMQL's rom is fixed at the 1st MB address, and DDR start* from the 1st MB address, it is not the same with zynq!!!!* No scu filter function for it!!! */
#define MEM_BASE_ADDR				0x01000000
#define RX_INTR_ID					PL0_INT_ID
// #define RX_INTR_ID				XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID
#define TX_INTR_ID					XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID
#define INTC  						FGicPs/* Timeout loop counter for reset*/
#define RESET_TIMEOUT_COUNTER		10000
#define TEST_START_VALUE			0xC
/** Buffer and Buffer Descriptor related constant definition* 长度取决于axi dma ip的配置: Width of Buffer Length Register(8-26) 设置* 驱动默认设置为23bit, 测试vivado工程里配置为26bit*/
#define CONFIG_SYS_CACHELINE_SIZE  	(64)
#define CONFIG_SYS_CACHELINE_MASK	(CONFIG_SYS_CACHELINE_SIZE - 1)
#define MAX_PKT_LEN					(XAXIDMA_MAX_TRANSFER_LEN & (~CONFIG_SYS_CACHELINE_MASK))
#define PIXEL_LEN					(640 & (~CONFIG_SYS_CACHELINE_MASK))
#define NUMBER_OF_TRANSFERS			10#define TX_BUFFER_BASE				(MEM_BASE_ADDR)
#define RX_BUFFER_BASE				(MEM_BASE_ADDR + MAX_PKT_LEN)
//#define RX_BUFFER_HIGH			(MEM_BASE_ADDR + 0x004FFFFF)/* SD卡 */
// #define FWRITE_READ_BUFFER_SIZE_MAX (8*1024*1024)  /*读写压力测试的buffer大小,不需要4字节对齐、64字节对齐或512字节对齐等限制*/
#define FWRITE_READ_BUFFER_SIZE_MAX (2*640*512)  /*读写压力测试的buffer大小,不需要4字节对齐、64字节对齐或512字节对齐等限制*/
#define CONFIG_VOLUMES_NUM 			(4)  /*确保CONFIG_VOLUMES_NUM ≤ 4,给每个sdmmc预留了最多4个分区*/
#define MANUAL_FORCE_FDISK_EN  		0  /*如果想把SD/EMMC里已有的分区删除变成裸盘,配置为1,否则为0*//************************** Function Prototypes ******************************/#ifdef XPAR_UARTNS550_0_BASEADDR
static void Uart550_Setup(void);
#endif// static int CheckData(int Length, u8 StartValue);
static void TxIntrHandler(void *Callback);
static void RxIntrHandler(void *Callback);static int 	SetupIntrSystem(INTC * IntcInstancePtr,XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId);
static void DisableIntrSystem(INTC * IntcInstancePtr,u16 TxIntrId, u16 RxIntrId);
/* sd卡 */
u32 		fmsh_SdEmmcInitPartFAT32(u32 ulPhyDriveNo,u32 ulPartitionNum,DWORD plist[]);
FRESULT 	scan_files (TCHAR* path);
FRESULT 	scan_dirs (TCHAR* path);
void 		fdisk_physicaldrive (u32 ulPhyDriveNo);
FRESULT 	remove_file(TCHAR* path);
FRESULT 	rm_all_files_in_dir(TCHAR* path);
FRESULT 	rm_all_empty_dir(TCHAR* path);
void 		show_all_file_info_of_dir(TCHAR* path);
void 		show_all_dir_of_partition(TCHAR* path);
void 		remove_all_dirs(TCHAR* path);
void 		remove_one_dir_or_file(TCHAR* path);
FRESULT 	show_partition_usage(u32 ulPhyDriveNo,u32 ulPartitionNum);
u32 		upload_bin_to_sdmmc(char* host_file,char* dst_path);
u32 		sdmmc_wr_rd_test(u32 ulPhyDriveNo,u32 ulPartitionNum);void 		FDmaPs_IRQ (void *InstancePtr);/************************** Variable Definitions *****************************/
/** Device instance definitions*/static 	XAxiDma 	AxiDma;		/* Instance of the XAxiDma */
FGpioPs_T 			g_gpios;
// FGpioPs_Config 		*gpio_cfgPpr;
/** Flags interrupt handlers use to notify the application context the events.*/
volatile int 		TxDone;
volatile int 		RxDone;
volatile int 		Error;
/* sd卡 */
FATFS 				fatfs[FF_VOLUMES];
BYTE 				f_mkfsBuff[FF_VOLUMES][FF_MAX_SS];
/*由于使用了dcache,指定起始地址以cacheline size对齐*/
BYTE 				work[FF_MAX_SS] __attribute__ ((aligned (CONFIG_SYS_CACHELINE_SIZE)));  /* Working buffer */
/*由于使用了dcache,指定起始地址以cacheline size对齐*/
char 				m_dir_buffer[256] __attribute__ ((aligned (CONFIG_SYS_CACHELINE_SIZE)));/*假定目录名最大255个字节,预留一个字符结束符位置*//* Volume mapping table (FF_MULTI_PARTITION == 1) */
/*每个物理盘最多4个分区*/
PARTITION VolToPart[FF_VOLUMES] = {{0, 1},    /* "0:" ==> 1st partition in PD#0 */{0, 2},    /* "1:" ==> 2nd partition in PD#0 */{0, 3},    /* "2:" ==> 3nd partition in PD#0 */{0, 4},    /* "3:" ==> 4th partition in PD#0 */{1, 1},    /* "4:" ==> 1st partition in PD#1 */{1, 2},    /* "5:" ==> 2nd partition in PD#1 */{1, 3},    /* "6:" ==> 3nd partition in PD#1 */{1, 4}     /* "7:" ==> 4th partition in PD#1 */    
};FDmaPs_T 			g_DMA_dmac;
FDmaPs_Param_T 		g_DMA_param;
FDmaPs_Instance_T 	g_DMA_instance;#define FMSH_ReadData8(baseAddr, offSet)		*((volatile unsigned char *)(baseAddr + offSet))
#define FMSH_WriteData8(baseAddr, offSet, data)	*((volatile unsigned char *)(baseAddr + offSet)) = data   
#define FMSH_ReadData16(baseAddr, offSet)		*((volatile u16 *)(baseAddr + offSet))
#define FMSH_WriteData16(baseAddr, offSet, data)	*((volatile u16 *)(baseAddr + offSet)) = data   /* 地址adr对齐的示例代码const u32 CACHE_LINE = 64U;u32 adr = (u32)malloc(DMA_LENGTH + 2*CACHE_LINE);//对齐CACHE_LINEadr += CACHE_LINE;adr &= ~(CACHE_LINE - 1U);g_txDma_mgr.orig_ptr =(u8*) adr;长度对齐:从DDR更新DCacheif(g_tcp_mgr.total_byte_num % CACHE_LINE>0){ dcacheInvalidLen = (g_tcp_mgr.total_byte_num / CACHE_LINE + 1)*CACHE_LINE; }else{ dcacheInvalidLen = (g_tcp_mgr.total_byte_num ;  }Xil_DCacheInvalidateRange((INTPTR)g_rxDma_mgr.orig_ptr, dcacheInvalidLen );*/void FDmaPs_IRQ (void *InstancePtr)
{FDmaPs_irqHandler((FDmaPs_T *)InstancePtr);
}/****************************************************************************************************************
* u32 ulPhyDriveNo---physical drive number : 0 or 1
* u32 ulPartitionNum----logical partition number of a physical drive:1,2,3 or 4
* DWORD plist[]----List of partition size to create on the physical drive eg:{50, 50, 0, 0};  Divide the drive into two equal partitions {0x10000000,50,50,0}; 256M sectors for 1st partition and 50% of the left for 2nd partition and 3nd partition each{20, 20, 20, 0}; 20% for 3 partitions each and remaing space is left not allocated{25, 25, 25, 25}; 25% for 4 partitions each{100, 0, 0, 0}; only one partition,all allocated to this partition
*****************************************************************************************************************/
u32 fmsh_SdEmmcInitPartFAT32(u32 ulPhyDriveNo,u32 ulPartitionNum,DWORD plist[])
{FRESULT Res = FR_OK;TCHAR *Path[] = {"0:","1:","2:","3:","4:","5:","6:","7:"};/*Logical drive number */u32 i;if(CONFIG_VOLUMES_NUM < ulPartitionNum){return FMSH_FAILURE;  }if(SDMMCPS_0_DEVICE_ID == ulPhyDriveNo){FDmaPs_T *pDmac = &g_DMA_dmac;FDmaPs_Instance_T *pInstance = &g_DMA_instance;FDmaPs_Param_T *pParam = &g_DMA_param;FDmaPs_Config *pDmaCfg;s32 Status;/*step1~step3的顺序不能调整,这3步作为整体放在sdmmc DMA操作之前*//*step1: gic初始化 ,使用DMA中断模式必需*/FGicPs_SetupInterruptSystem(&IntcInstance);FMSH_ExceptionRegisterHandler(FMSH_EXCEPTION_ID_IRQ_INT,(FMSH_ExceptionHandler)FGicPs_InterruptHandler_IRQ,&IntcInstance); /*step2: Initialize the DMA Driver */pDmaCfg = FDmaPs_LookupConfig(FPAR_DMAPS_DEVICE_ID);if (pDmaCfg == NULL) {return FMSH_FAILURE;}FDmaPs_initDev(pDmac, pInstance, pParam, pDmaCfg);Status = FGicPs_registerInt(&IntcInstance, DMA_INT_ID,(FMSH_InterruptHandler)FDmaPs_IRQ, pDmac);if (Status != FMSH_SUCCESS){return FMSH_FAILURE;}Status = FDmaPs_autoCompParams(pDmac);if (Status != FMSH_SUCCESS){return FMSH_FAILURE;}/*step3: 设置sdmmc工作在DMA模式下,只有sdmmc0支持DMA方式 */set_sdmmc_workmode(sdmmc_trans_mode_dw_dma);}for(i=0;i < ulPartitionNum;i++){/* Try to mount FAT file system */Res |= f_mount(&fatfs[i+4*ulPhyDriveNo], Path[i+4*ulPhyDriveNo], 1);}if (Res != FR_OK) {        fmsh_print("Volume is not FAT formatted, formatting FAT32,please waiting......\r\n");Res = f_fdisk(ulPhyDriveNo, plist, work);  /* Divide physical drive */if (Res != FR_OK) {fmsh_print("f_fdisk err[%d]!\r\n",Res);return FMSH_FAILURE;}else{fmsh_print("f_fdisk OK!\r\n");}for(i=0;i < ulPartitionNum;i++){/*make FAT32 fs for each partition*/Res = f_mkfs(Path[i+4*ulPhyDriveNo], FM_FAT32, 0, f_mkfsBuff[i+4*ulPhyDriveNo], sizeof(f_mkfsBuff[i+4*ulPhyDriveNo]));if (Res != FR_OK) {fmsh_print("Unable to format FATfs[%d],err[%d]\r\n",i,Res);return FMSH_FAILURE;}else{fmsh_print("partition[%d],mkfs FAT32 OK!\r\n",i);}Res = f_mount(&fatfs[i+4*ulPhyDriveNo], Path[i+4*ulPhyDriveNo], 1);if (Res != FR_OK) {fmsh_print("Unable to mount FATfs[%d],err[%d]\r\n",i,Res);return FMSH_FAILURE;}else{fmsh_print("partition[%d],mount FAT32 OK!\r\n",i);}}}// (void)show_partition_usage(ulPhyDriveNo,ulPartitionNum);fmsh_print("File system initialization successful\r\n");return FMSH_SUCCESS;
}// FRESULT scan_files (TCHAR* path)
// {
//     FRESULT rc;	 /* Result code */
// 	DIR dir;
// 	static FILINFO fno;
// 	UINT i;// 	rc = f_opendir (&dir,path);
// 	if(FR_OK == rc)
// 	{
// 		for (;;) 
// 		{
// 			rc = f_readdir(&dir, &fno); /* Read a directory item */
// 			if (rc != FR_OK || fno.fname[0] == 0) 
// 				break;  /* Break on error or end of dir */
// 			if (fno.fattrib & AM_DIR) 
// 			{   /* It is a directory */
// 			    i = strlen(path);
// 			    sprintf(&path[i], "/%s", fno.fname);
// 			    rc = scan_files(path);  /* Enter the directory */
// 			    if (rc != FR_OK) 
//                   break;
// 			    path[i] = 0;
// 			} else 
// 			{   /* It is a file. */
// 			    fmsh_print("%s/%s Size: %lu  Timestamp: %u/%02u/%02u, %02u:%02u Attributes: %c%c%c%c%c\r\n",\
// 					path, fno.fname,fno.fsize,(fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,\
// 	               fno.ftime >> 11, fno.ftime >> 5 & 63,\
// 	               (fno.fattrib & AM_DIR) ? 'D' : '-',\
// 	               (fno.fattrib & AM_RDO) ? 'R' : '-',\
// 	               (fno.fattrib & AM_HID) ? 'H' : '-',\
// 	               (fno.fattrib & AM_SYS) ? 'S' : '-',\
// 	               (fno.fattrib & AM_ARC) ? 'A' : '-');
// 			}
// 		}
// 		f_closedir(&dir);
// 	}
// 	else
// 	{
// 		fmsh_print("directory [%s] not exist!\r\n",path);
// 		return FR_NO_PATH;
// 	}
//     return rc;
// }// FRESULT scan_dirs (TCHAR* path)
// {
//     FRESULT rc;	 /* Result code */
// 	DIR dir;
// 	static FILINFO fno;
// 	UINT i;// 	rc = f_opendir (&dir,path);
// 	if(FR_OK == rc)
// 	{
// 		for (;;) 
// 		{
// 			rc = f_readdir(&dir, &fno); /* Read a directory item */
// 			if (rc != FR_OK || fno.fname[0] == 0) 
// 				break;  /* Break on error or end of dir */
// 			if (fno.fattrib & AM_DIR) 
// 			{   /* It is a directory */
// 				fmsh_print("%s/%s Size: %lu  Timestamp: %u/%02u/%02u, %02u:%02u Attributes: %c%c%c%c%c\r\n",\
// 					path, fno.fname,fno.fsize,(fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,\
// 	               fno.ftime >> 11, fno.ftime >> 5 & 63,\
// 	               (fno.fattrib & AM_DIR) ? 'D' : '-',\
// 	               (fno.fattrib & AM_RDO) ? 'R' : '-',\
// 	               (fno.fattrib & AM_HID) ? 'H' : '-',\
// 	               (fno.fattrib & AM_SYS) ? 'S' : '-',\
// 	               (fno.fattrib & AM_ARC) ? 'A' : '-');
// 			    i = strlen(path);
// 			    sprintf(&path[i], "/%s", fno.fname);
// 			    rc = scan_dirs(path);  /* Enter the directory */
// 			    if (rc != FR_OK) 
//                   break;
// 			    path[i] = 0;
// 			} else 
// 			{   /* It is a file. */
// 			}
// 		}
// 		f_closedir(&dir);
// 	}
// 	else
// 	{
// 		fmsh_print("directory [%s] not exist!\r\n",path);
// 		return FR_NO_PATH;
// 	}
//     return rc;
// }// void fdisk_physicaldrive (u32 ulPhyDriveNo)
// {
//    /* 将MANUAL_FORCE_FDISK_EN配置为1,删除已有的分区,变成裸盘,正常流程配置为0,不走该流程*/
// 	DWORD force_fdisk_plist[] = {0, 0, 0, 0}; 
// 	FRESULT rc;	 /* Result code */// 	fmsh_print("warning!!!,data on disk will lost!\r\n");
// 	rc = f_fdisk(ulPhyDriveNo, force_fdisk_plist, work);  /* Divide physical drive */
// 	if (rc != FR_OK) 
// 	{
// 	  fmsh_print("force f_fdisk err[%d]!\r\n",rc);
// 	  return ;
// 	}
// 	else
// 	{
// 	  fmsh_print("force f_fdisk OK!\r\n");
// 	  return ;
// 	}
// }// FRESULT remove_file(TCHAR* path)
// {
// 	FRESULT rc; 	/* Result code */// 	rc = f_unlink(path);
// 	if (rc != FR_OK) 
// 	{
// 	  fmsh_print("remove %s err[%d]!\r\n",path,rc);
// 	}
// 	else
// 	{
// 	  fmsh_print("remove %s OK!\r\n",path);
// 	}
// 	return rc;
// }// TCHAR path_buf[256]={0};/*假定文件名+目录名最大255个字节,预留一个字符结束符位置*/
// /*遍历删除path指定的目录及其子目录下的所有文件*/
// FRESULT rm_all_files_in_dir(TCHAR* path)
// {
//     FRESULT rc;	 /* Result code */
// 	DIR dir;
// 	static FILINFO fno;
// 	UINT i;
// 	TCHAR* pfname_buf;
// 	u32 ulPathlen;// 	strcpy(path_buf,path);// 	rc = f_opendir (&dir,path);
// 	if(FR_OK == rc)
// 	{
// 		for (;;) 
// 		{
// 			rc = f_readdir(&dir, &fno); /* Read a directory item */
// 			if (rc != FR_OK || fno.fname[0] == 0) 
// 				break;  /* Break on error or end of dir */
// 			if (fno.fattrib & AM_DIR) 
// 			{   /* It is a directory */
// 			    i = strlen(path_buf);
// 			    sprintf(&path_buf[i], "/%s", fno.fname);
// 			    rc = rm_all_files_in_dir(path_buf);  /* Enter sub directory */
// 			    if (rc != FR_OK) 
//                   break;
// 			    path_buf[i] = 0;
// 			} 
// 			else 
// 			{   /* It is a file,delete the file*/
// 				ulPathlen = strlen(path_buf);
// 				pfname_buf = strcat(path_buf,"/");
// 			    pfname_buf = strcat(pfname_buf,fno.fname);
// 				rc = f_unlink(pfname_buf);
// 				if (rc != FR_OK) 
// 				{
// 				  fmsh_print("remove %s err[%d]!\r\n",pfname_buf,rc);
// 				}
// 				else
// 				{
// 				  fmsh_print("remove %s OK!\r\n",pfname_buf);
//                   path_buf[ulPathlen]= 0x0;
// 				}
// 			}
// 		}
// 		f_closedir(&dir);
// 	}
// 	else
// 	{
// 		fmsh_print("directory [%s] not exist!\r\n",path);
// 		return FR_NO_PATH;
// 	}
//     return rc;
// }// /*删除path指定的空目录及其子目录下,确保目录下没有文件,否则会删除失败*/
// FRESULT rm_all_empty_dir(TCHAR* path)
// {
//     FRESULT rc;	 /* Result code */
// 	DIR dir;
// 	static FILINFO fno;
// 	UINT i;
// 	TCHAR* pfname_buf = path_buf;// 	strcpy(pfname_buf,path);// 	rc = f_opendir (&dir,path);
// 	if(FR_OK == rc)
// 	{
// 		for (;;) 
// 		{
// 			rc = f_readdir(&dir, &fno); /* Read a directory item */
// 			if (rc == FR_OK)
// 			{
// 				if(fno.fname[0] == 0)
// 				{
// 					f_closedir(&dir);// 					rc = f_unlink(pfname_buf);
// 					if (rc != FR_OK) 
// 					{
// 					  fmsh_print("remove %s err[%d]!\r\n",pfname_buf,rc);
// 					}
// 					else
// 					{
// 					  fmsh_print("remove %s OK!\r\n",pfname_buf);
// 	                  //path_buf[ulPathlen]= 0x0;
// 					}
// 					return rc;
// 				}
// 				else
// 				{
// 					if (fno.fattrib & AM_DIR) 
// 					{	/* It is a directory */
// 						i = strlen(pfname_buf);
// 						sprintf(&pfname_buf[i], "/%s", fno.fname);
// 						rc = rm_all_empty_dir(pfname_buf);  /* Enter sub directory */
// 						if (rc != FR_OK) 
// 						  break;
// 						pfname_buf[i] = 0;
// 					} 
// 					else 
// 					{	/* It is a file,skip*/
// 					   fmsh_print("directory [%s] not empty!\r\n",fno.fname);
// 					   return FR_DENIED;// 					}
// 				}
// 			}
// 			else
// 			{
// 				break;  /* Break on error or end of dir */
// 			}
// 		}// 		f_closedir(&dir);
// 	}
// 	else
// 	{
// 		fmsh_print("directory [%s] not exist!\r\n",path);
// 		return FR_NO_PATH;
// 	}
//     return rc;
// }// /*遍历显示path指定的目录所有文件的信息*/
// void show_all_file_info_of_dir(TCHAR* path)
// {
// 	scan_files(path);
// 	return;
// }// /*遍历显示path指定的partition所有目录及子目录*/
// void show_all_dir_of_partition(TCHAR* path)
// {
// 	scan_dirs(path);
// 	return;
// }// /*删除path指定的目录、子目录下的所有文件,还有目录和子目录*/
// void remove_all_dirs(TCHAR* path)
// {
// 	if(FR_OK == rm_all_files_in_dir(path))
// 	{
// 		rm_all_empty_dir(path);
// 	}// 	return;
// }// /*删除path指定的某个目录或者文件,如果目录非空则会删除失败*/
// void remove_one_dir_or_file(TCHAR* path)
// {
//     FRESULT rc;	 /* Result code */
// 	rc = f_unlink(path);
// 	if (rc != FR_OK) 
// 	{
// 	  fmsh_print("remove %s err[%d]!\r\n",path,rc);
// 	}
// 	else
// 	{
// 	  fmsh_print("remove %s OK!\r\n",path);
// 	}// 	return;
// }// /*显示指定逻辑分区的容量信息及剩余容量信息*/
// FRESULT show_partition_usage(u32 ulPhyDriveNo,u32 ulPartitionNum)
// {
// 	FRESULT Res = FR_OK;
// 	TCHAR *Path[] = {"0:","1:","2:","3:","4:","5:","6:","7:"};/*Logical drive number */
// 	u32 i;
// 	DWORD fre_clust, fre_sect, tot_sect;
// 	FATFS *fs;// 	for(i=0;i < ulPartitionNum;i++)
// 	{	
// 		/* Get total sectors and free sectors */
// 		Res = f_getfree(Path[i+4*ulPhyDriveNo], &fre_clust, &fs);
// 		if (Res)
// 		{
// 		  fmsh_print("f_getfree err[%d]!\r\n",Res);
// 		  continue;
// 		}
// 		tot_sect = (fs->n_fatent - 2) * fs->csize;
// 		fre_sect = fre_clust * fs->csize;
// 		/*如果sector size不是512字节时,使用(tot_sect*fs->ssize)/ 1024, (fre_sect*fs->ssize) / 1024);*/
// 		fmsh_print("partition [%d] :%10lu KiB total space.%10lu KiB available.\r\n", i,tot_sect/2, fre_sect/2);/*sector size = 512 bytes*/
// 	}
// 	return Res;
// }// /*通过IAR jlink上传主机上的bin文件到sdmmc中指定的目录*/
// u32 upload_bin_to_sdmmc(char* host_file,char* dst_path)
// {
//     FILE *fptr = NULL;
// 	size_t rdsize;
// 	long fileLen;
// 	char *pbuf;//     FIL fileinst;
//     FIL *fp = &fileinst;
// 	FRESULT rc;	 /* Result code */
// 	u32 ulbw;// 	fptr = fopen(host_file,"rb");
// 	if(NULL != fptr)
// 	{
// 	    fseek(fptr,0,SEEK_END);
// 		fileLen = ftell(fptr);
// 		fseek(fptr,0,SEEK_SET);
// 		if(-1 != fileLen)
// 		{
// 			pbuf = malloc(fileLen);
// 			rdsize = fread(pbuf,1,fileLen,fptr);
// 			if(rdsize == fileLen)
// 			{
// 				rc = f_open(fp, dst_path, FA_CREATE_ALWAYS|FA_WRITE);/*追加写入方式打开*/
// 				if (rc) 
// 				{
// 				  fmsh_print("Unable to create file %s: %d\r\n", dst_path, rc);
// 				  fclose(fptr);
// 				  free(pbuf);
// 				  return FMSH_FAILURE;
// 				}	// 				rc= f_write(fp,(void*)pbuf, fileLen, &ulbw);
// 				if(rc || (fileLen != ulbw))
// 				{
// 					fmsh_print("update bin %s failed.\r\n",host_file);
// 					fclose(fptr);
// 				    free(pbuf);
// 					f_close(fp);
// 					return FMSH_FAILURE;
// 				}
// 			}
// 			else
// 			{
// 				fmsh_print("read bin %s failed.\r\n",host_file);
// 				fclose(fptr);
// 				free(pbuf);
// 				return FMSH_FAILURE;
// 			}
// 		}
// 		else
// 		{
// 			fmsh_print("get bin %s length failed.\r\n",host_file);
// 			fclose(fptr);
// 			return FMSH_FAILURE;
// 		}
// 	}
// 	else
// 	{
// 		fmsh_print("open bin %s failed.\r\n",host_file);
// 	    return FMSH_FAILURE;		
// 	}// 	fclose(fptr);
// 	free(pbuf);
// 	f_close(fp);
// 	fmsh_print("update bin %s OK!\r\n",host_file);
// 	return FMSH_SUCCESS;
// }// u32 sdmmc_wr_rd_test(u32 ulPhyDriveNo,u32 ulPartitionNum)
// {
//     FIL fileinst;
//     FIL *fp = &fileinst;
//     FRESULT rc;	 /* Result code */
// 	//u32 ulret = FMSH_SUCCESS;
//     char *pwbuf = NULL;
//     char *pwbuf_AlignStart;
// 	char *pwbuf_AlignEnd;
//     char *prbuf = NULL;
//     char *prbuf_AlignStart;
//     char *prbuf_AlignEnd;
//     u32 ulbw,ulbr;
//     FSIZE_t fileLen;
// 	TCHAR *Path[] = {"0:","1:","2:","3:","4:","5:","6:","7:"};/*Logical drive number */
//     char filename[32]={0};
//     u32 i,j,k;
//     u64 Pretime = 0;
//     u64 Curtime = 0;
//     u64 timeUsed = 0;
// 	FSIZE_t  fp_offset;// 	DWORD fre_clust, fre_sect;
// 	FATFS *fs;
// 	TCHAR *subdir[FF_VOLUMES] = {"/subdir0","/subdir1","/subdir2","/subdir3","/subdir4","/subdir5","/subdir6","/subdir7"};/*子目录名称 */
// 	FILINFO finfo;// 	if(CONFIG_VOLUMES_NUM < ulPartitionNum)
// 	{
// 		return FMSH_FAILURE;  
// 	}// 	pwbuf = malloc(FWRITE_READ_BUFFER_SIZE_MAX + 2*CONFIG_SYS_CACHELINE_SIZE);
// 	if(NULL == pwbuf)
// 	{
// 		fmsh_print("pwbuf malloc err\r\n");
// 		return FMSH_FAILURE;
// 	}
// 	/*由于使用了dcache,使用的buffer起始地址以cacheline size对齐,大小也需要以cacheline size对齐*/
// 	pwbuf_AlignStart = (char *)(((u32)pwbuf + CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));
// 	pwbuf_AlignEnd = (char *)(((u32)pwbuf_AlignStart +FWRITE_READ_BUFFER_SIZE_MAX+ CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));// 	prbuf = malloc(FWRITE_READ_BUFFER_SIZE_MAX + 2*CONFIG_SYS_CACHELINE_SIZE);
// 	if(NULL == prbuf)
// 	{
// 		fmsh_print("prbuf malloc err\r\n");
// 		free(pwbuf);
// 		return FMSH_FAILURE;
// 	}
// 	/*由于使用了dcache,使用的buffer起始地址以cacheline size对齐,大小也需要以cacheline size对齐*/
// 	prbuf_AlignStart = (char *)(((u32)prbuf + CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));
// 	prbuf_AlignEnd = (char *)(((u32)prbuf_AlignStart +FWRITE_READ_BUFFER_SIZE_MAX+ CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));// 	fmsh_print("sdmmc%d FAT32 baremetal test start.....\r\n",ulPhyDriveNo);
// 	for(i=0;i < 3;i++)/*连续测试多次,测试追加写入功能*/
// 	{	 
// 		fmsh_print("%d round test in progress.....\r\n",i+1);
// 		for(k = 0;k < ulPartitionNum;k++)/*多个分区*/
// 		{
// 		  /*假定sdmmc0和sdmmc1均有4个分区*/
// 		  f_chdrive(Path[k+4*ulPhyDriveNo]);/*Change Current Drive*/
// 		  strcpy(m_dir_buffer,subdir[k+4*ulPhyDriveNo]);// 		  if(FR_OK != f_stat(m_dir_buffer, &finfo))
// 		  {
// 			  rc = f_mkdir(m_dir_buffer);
// 			  if (rc)
// 			  {
// 				  free(pwbuf);
// 				  free(prbuf);
// 				  return FMSH_FAILURE;
// 			  }
// 		  }
// 		  //scan_files(subdir[k]);// 		  if(FR_OK != f_chdir(m_dir_buffer))
// 		  {
// 			  free(pwbuf);
// 			  free(prbuf);
// 			  return FMSH_FAILURE;
// 		  }// 		  for(j=0;j < 100;j++)/*生成100个文件*/
// 		  {
// 			  /* Get volume information and free clusters of drive */
// 			  rc = f_getfree(Path[k+4*ulPhyDriveNo], &fre_clust, &fs);
// 			  if (rc)
// 			  {
// 				  free(pwbuf);
// 				  free(prbuf);
// 				  return FMSH_FAILURE;
// 			  }// 			  /* Get free sectors */
// 			  fre_sect = fre_clust * fs->csize;
// 			  /*如果sector size不是512字节时,使用fs->ssize*/
// 			  if(fre_sect < (FWRITE_READ_BUFFER_SIZE_MAX/512))/*sector size = 512 bytes */
// 			  {
// 				fmsh_print("partition[%d]:left space not enough to write:%10lu KiB available.\r\n",k,fre_sect/2);
// 				 break;
// 			  } 		  // 			sprintf(filename, "test%d.bin",j);
// 			rc = f_open(fp, filename, FA_OPEN_APPEND|FA_READ|FA_WRITE);/*追加写入方式打开*/
// 			if (rc) 
// 			{
// 			  fmsh_print("Unable to open file %s: %d\r\n", filename, rc);
// 			  free(pwbuf);
// 			  free(prbuf);
// 			  return FMSH_FAILURE;
// 			}	// 			memset(pwbuf_AlignStart,0x5a+j+i+k,FWRITE_READ_BUFFER_SIZE_MAX);
// 	#if PSOC_CACHE_ENABLE
// 			flush_dcache_range((u32)pwbuf_AlignStart,(u32)pwbuf_AlignEnd);
// 	#endif// 			Pretime = get_current_time();		  
// 			rc= f_write(fp,(void*)pwbuf_AlignStart, FWRITE_READ_BUFFER_SIZE_MAX, &ulbw);
// 			if(rc || (FWRITE_READ_BUFFER_SIZE_MAX != ulbw))
// 			{
// 				fmsh_print("Write File To SD EMMC Card Failed[%d].\r\n",rc);
// 				f_close(fp);
// 				free(pwbuf);
// 				free(prbuf);
// 				return FMSH_FAILURE;
// 			}			 
// 			//f_sync(fp);/*flush cached data into file*/// 			fileLen = f_size(fp);// 			Curtime = get_current_time();
// 			timeUsed = (Curtime - Pretime)/GTC_CLK_FREQ/1000;
// 			fmsh_print("FAT32 partition[%d]: write file[%d]--size[0x%x],Use time: %lldms,speed:%fKiB/s\r\n",k,j,fileLen,timeUsed,(double)(FWRITE_READ_BUFFER_SIZE_MAX)/timeUsed/1.024);// 			fp_offset = f_tell(fp);
// 			f_close(fp);/*关闭当前文件*/// 			rc = f_open(fp, filename, FA_READ);/*只读方式打开*/
// 			if (rc) 
// 			{
// 			  fmsh_print("Unable to open file %s: %d\r\n", filename, rc);
// 			  free(pwbuf);
// 			  free(prbuf);
// 			  return FMSH_FAILURE;
// 			} // 			/*回读校验*/
// 			fp_offset = fp_offset - FWRITE_READ_BUFFER_SIZE_MAX;
// 			rc = f_lseek(fp,fp_offset);/*将文件指针设置到上次写入的起始位置,进行回读校验*/
// 			if(rc)
// 			{
// 			  fmsh_print("f_lseek err Failed[%d],fp_offset:%d\r\n",rc,fp_offset);
// 				f_close(fp);
// 				free(pwbuf);
// 				free(prbuf);
// 				return FMSH_FAILURE;
// 			}		
// 			rc = f_read(fp,prbuf_AlignStart,ulbw,&ulbr);
// 			if(rc || (ulbr != ulbw))
// 			{
// 				fmsh_print("read FAT32 partition[%d] file[%d] err\r\n",k,j);
// 			}
// 	#if PSOC_CACHE_ENABLE
// 			flush_dcache_range((u32)prbuf_AlignStart,(u32)prbuf_AlignEnd);
//     #endif
// 			if(0 != memcmp(prbuf_AlignStart,pwbuf_AlignStart,FWRITE_READ_BUFFER_SIZE_MAX))
// 			{
// 				fmsh_print("FAT32 partition[%d] file[%d] readback check err\r\n",k,j);
// 				free(pwbuf);
// 				free(prbuf);
// 				f_close(fp);
// 				return FMSH_FAILURE;				
// 			}
// 			else
// 			{
// 				fmsh_print("FAT32 partition[%d] file[%d]--size[0x%x] readback check OK!\r\n",k,j,fileLen);
// 			}// 			rc= f_close(fp);/*关闭当前文件*/
// 			if(rc)
// 			{
// 				free(pwbuf);
// 				free(prbuf);
// 				return FMSH_FAILURE;
// 			}
// 		  }
// 		}
// 		fmsh_print("%d round test finish.....\r\n",i+1);
// 	}	
// 	fmsh_print("sdmmc%d FAT32 baremetal demo works good!!!\r\n",ulPhyDriveNo);
// 	free(pwbuf);
// 	free(prbuf);// 	return FMSH_SUCCESS;// }#ifdef XPAR_UARTNS550_0_BASEADDR
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600 and data bits to 8
*
* @param	None
*
* @return	None
*
* @note		None.
*
******************************************************************************/
static void Uart550_Setup(void)
{XUartNs550_SetBaud(XPAR_UARTNS550_0_BASEADDR,XPAR_XUARTNS550_CLOCK_HZ, 9600);XUartNs550_SetLineControlReg(XPAR_UARTNS550_0_BASEADDR,XUN_LCR_8_DATA_BITS);
}
#endif/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* We use the static tx/rx buffers.
*
* @param	Length is the length to check
* @param	StartValue is the starting value of the first byte
*
* @return
*		- XST_SUCCESS if validation is successful
*		- XST_FAILURE if validation is failure.
*
* @note		None.
*
******************************************************************************/
// static int CheckData(int Length, u8 StartValue)
// {
// 	u8 *RxPacket;
// 	int Index = 0;
// 	u8 Value;// 	RxPacket = (u8 *) RX_BUFFER_BASE;
// 	Value = StartValue;// 	/* Invalidate the DestBuffer before receiving the data, in case the
// 	 * Data Cache is enabled
// 	 */
// 	invalidate_dcache_range((UINTPTR)RxPacket, (UINTPTR)RxPacket + Length);// 	for(Index = 0; Index < Length; Index++) {
// 		// xil_printf("Data%d is: %x/%x\r\n",Index, RxPacket[Index], Value);
// 		if (RxPacket[Index] != Value) {
// 			xil_printf("Data error %d: %x/%x\r\n",
// 			    Index, RxPacket[Index], Value);// 			return XST_FAILURE;
// 		}
// 		Value = (Value + 1) & 0xFF;
// 	}// 	return XST_SUCCESS;
// }/*****************************************************************************/
/*
*
* This is the DMA TX Interrupt handler function.
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then sets the TxDone.flag
*
* @param	Callback is a pointer to TX channel of the DMA engine.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
static void TxIntrHandler(void *Callback)
{u32 IrqStatus;int TimeOut;XAxiDma *AxiDmaInst = (XAxiDma *)Callback;/* Read pending interrupts */IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DMA_TO_DEVICE);/* Acknowledge pending interrupts */XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DMA_TO_DEVICE);/** If no interrupt is asserted, we do not do anything*/if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {return;}/** If error interrupt is asserted, raise error flag, reset the* hardware to recover from the error, and return with no further* processing.*/if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {Error = 1;/** Reset should never fail for transmit channel*/XAxiDma_Reset(AxiDmaInst);TimeOut = RESET_TIMEOUT_COUNTER;while (TimeOut) {if (XAxiDma_ResetIsDone(AxiDmaInst)) {break;}TimeOut -= 1;}return;}/** If Completion interrupt is asserted, then set the TxDone flag*/if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {TxDone = 1;}// xil_printf(" Tx intr:txDone is %d\r\n",TxDone);
}/*****************************************************************************/
/*
*
* This is the DMA RX interrupt handler function
*
* It gets the interrupt status from the hardware, acknowledges it, and if any
* error happens, it resets the hardware. Otherwise, if a completion interrupt
* is present, then it sets the RxDone flag.
*
* @param	Callback is a pointer to RX channel of the DMA engine.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
static void RxIntrHandler(void *Callback)
{u32 IrqStatus;int TimeOut;XAxiDma *AxiDmaInst = (XAxiDma *)Callback;/* Read pending interrupts */IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DEVICE_TO_DMA);/* Acknowledge pending interrupts */XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DEVICE_TO_DMA);/** If no interrupt is asserted, we do not do anything*/if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {return;}/** If error interrupt is asserted, raise error flag, reset the* hardware to recover from the error, and return with no further* processing.*/if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {Error = 1;/* Reset could fail and hang* NEED a way to handle this or do not call it??*/XAxiDma_Reset(AxiDmaInst);TimeOut = RESET_TIMEOUT_COUNTER;while (TimeOut) {if(XAxiDma_ResetIsDone(AxiDmaInst)) {break;}TimeOut -= 1;}return;}/** If completion interrupt is asserted, then set RxDone flag*/if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {RxDone = 1;}// xil_printf(" rx intr:RxDone is %d\r\n",RxDone);
}/*****************************************************************************/
/*
*
* This function setups the interrupt system so interrupts can occur for the
* DMA, it assumes INTC component exists in the hardware system.
*
* @param	IntcInstancePtr is a pointer to the instance of the INTC.
* @param	AxiDmaPtr is a pointer to the instance of the DMA engine
* @param	TxIntrId is the TX channel Interrupt ID.
* @param	RxIntrId is the RX channel Interrupt ID.
*
* @return
*		- XST_SUCCESS if successful,
*		- XST_FAILURE.if not succesful
*
* @note		None.
*
******************************************************************************/
static int SetupIntrSystem(INTC * IntcInstancePtr,XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId)
{u32 Status;Status =  FGicPs_SetupInterruptSystem(IntcInstancePtr);if(Status!=GIC_SUCCESS){return GIC_FAILURE ;}/* The trigger type is not set in the peripheral test. */FGicPs_SetPriorityTriggerType(IntcInstancePtr, TxIntrId, 0xA0, 0x3);FGicPs_SetPriorityTriggerType(IntcInstancePtr, RxIntrId, 0xA0, 0x3);Status = FGicPs_Connect(IntcInstancePtr,TxIntrId,(FMSH_InterruptHandler)TxIntrHandler, AxiDmaPtr);if (Status != GIC_SUCCESS) {return GIC_FAILURE;}      Status = FGicPs_Connect(IntcInstancePtr,RxIntrId,(FMSH_InterruptHandler)RxIntrHandler, AxiDmaPtr);if (Status != GIC_SUCCESS) {return GIC_FAILURE;}      FMSH_ExceptionRegisterHandler(FMSH_EXCEPTION_ID_IRQ_INT,(FMSH_ExceptionHandler)FGicPs_InterruptHandler_IRQ,IntcInstancePtr);  FGicPs_Enable(IntcInstancePtr, TxIntrId);FGicPs_Enable(IntcInstancePtr, RxIntrId);return XST_SUCCESS;
}/*****************************************************************************/
/**
*
* This function disables the interrupts for DMA engine.
*
* @param	IntcInstancePtr is the pointer to the INTC component instance
* @param	TxIntrId is interrupt ID associated w/ DMA TX channel
* @param	RxIntrId is interrupt ID associated w/ DMA RX channel
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
static void DisableIntrSystem(INTC * IntcInstancePtr,u16 TxIntrId, u16 RxIntrId)
{FGicPs_Disconnect(IntcInstancePtr, TxIntrId);FGicPs_Disconnect(IntcInstancePtr, RxIntrId);
}/*****************************************************************************/
/**
*
* This function Transmission for dma
*
* @param	AxiDmaIns is the pointer to the AXIDMA component instance
* @param	wBuffer is Send buffer
* @param	length is send buffer length
*
* @return	成功返回XST_SUCCESS.失败返回XST_FAILURE
*
* @note		None.
*
******************************************************************************/
int pixel_dma_send(XAxiDma* AxiDmaIns,u16 *wBuffer, unsigned int length)
{int Status;u16 *TxBufferPtr;if((AxiDmaIns == NULL)||(wBuffer == NULL)){xil_printf("send Pointer err\r\n");return XST_FAILURE;}if (AxiDmaIns == &AxiDma)TxBufferPtr = (u16 *)TX_BUFFER_BASE ;else{xil_printf("para err\r\n");return XST_FAILURE;}memset(TxBufferPtr,0,length);memcpy(TxBufferPtr,wBuffer,length);// for(int Index = 0; Index < length; Index ++) {// 	TxBufferPtr[Index] = wBuffer[Index];// }flush_dcache_range((UINTPTR)TxBufferPtr, (UINTPTR)TxBufferPtr+MAX_PKT_LEN);Status = XAxiDma_SimpleTransfer(AxiDmaIns,(UINTPTR) TxBufferPtr,length, XAXIDMA_DMA_TO_DEVICE);
//	xil_printf("status is %d",Status);if (Status != XST_SUCCESS){return XST_FAILURE;}// xil_printf("\r\npixel_dma_send txdone is %d\r\n",TxDone);// TxDone = 0;return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function Transmission for dma
*
* @param	AxiDmaIns is the pointer to the AXIDMA component instance
* @param	rBuffer is recv buffer
*
* @return	length is rev buffer length
*
* @note		None.
*
******************************************************************************/
unsigned int pixel_dma_recv(XAxiDma* AxiDmaIns,u16 *rBuffer)
{int Status;unsigned int Length = 0 ;u16 *RxBufferPtr;while ( !RxDone && !Error) {/* NOP */}if (Error) {/* Compiler complain that it may not be support!! */if(!RxDone)xil_printf("Failed test receive not done\r\n");elsexil_printf("Failed test receive done\r\n");}Length = XAxiDma_ReadReg(AxiDmaIns->RegBase,0x58);if((AxiDmaIns == NULL)||(rBuffer == NULL)){xil_printf("recv Pointer err\r\n");return XST_FAILURE;}if (AxiDmaIns == &AxiDma)RxBufferPtr = (u16 *)RX_BUFFER_BASE ;else{xil_printf("pixel_dma_recv input para err\r\n");return XST_FAILURE;}// for(int Index = 0; Index < 32; Index++) // {// 	xil_printf("Data : %x\r\n", RxBufferPtr[Index]);// }// Length =MAX_PKT_LEN;invalidate_dcache_range((UINTPTR)RxBufferPtr, (UINTPTR)RxBufferPtr + MAX_PKT_LEN);Status = XAxiDma_SimpleTransfer(AxiDmaIns,(UINTPTR) RxBufferPtr,MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);if (Status != XST_SUCCESS) {return XST_FAILURE;}memset(rBuffer,0,Length);memcpy(rBuffer,RxBufferPtr,Length);// xil_printf("pixel_dma_recv:");// for(int Index = 0; Index < 32; Index++) // {// 	xil_printf("0x%x ", rBuffer[Index]);// }// invalidate_dcache_range((UINTPTR)RxBufferPtr,MAX_PKT_LEN);/* Invalidate the DestBuffer before receiving the data, in case the* Data Cache is enabled*/// for(int i = 0; i < Length; i++)// 	{// 		rBuffer[i] = RxBufferPtr[i];// 	}// memset(RxBufferPtr,0,Length);// memcpy(RxBufferPtr,rBuffer,Length);// flush_dcache_range((UINTPTR)RxBufferPtr, (UINTPTR)RxBufferPtr + MAX_PKT_LEN);// xil_printf("\r\npixel_dma_recv rxdone is %d\r\n",RxDone);RxDone = 0;return Length;
}
/*****************************************************************************/
/**
*
* This function for dma init
*
* @param	None.
*
* @return	成功返回XST_SUCCESS失败返回XST_FAILURE.
*
* @note		None.
*
******************************************************************************/
int pixel_dma_init(void)
{// xil_printf("\r\n--- 0Entering dma init() --- \r\n");int 			Status;// u16 			*TxBufferPtr;u16 			*RxBufferPtr;XAxiDma_Config 	*Config;// TxBufferPtr = (u16 *)TX_BUFFER_BASE ;RxBufferPtr = (u16 *)RX_BUFFER_BASE;// u8 *RxBufferPtr= (u8 *)RX_BUFFER_BASE;memset(RxBufferPtr,0,MAX_PKT_LEN);// xil_printf("\r\n--- Entering dma init() --- \r\n");Config = XAxiDma_LookupConfig(DMA_DEV_ID);if (!Config) {xil_printf("No config found for %d\r\n", DMA_DEV_ID);return XST_FAILURE;}// xil_printf("success config found for %d\r\n", DMA_DEV_ID);/* Initialize DMA engine */Status = XAxiDma_CfgInitialize(&AxiDma, Config);if (Status != XST_SUCCESS) {xil_printf("Initialization failed %d\r\n", Status);return XST_FAILURE;}// xil_printf("XAxiDma Initialization succeed %d\r\n", Status);if(XAxiDma_HasSg(&AxiDma)){xil_printf("Device configured as SG mode \r\n");return XST_FAILURE;}// xil_printf("Device configured as simple mode\r\n");/* Set up Interrupt system  */Status = SetupIntrSystem(&IntcInstance, &AxiDma, TX_INTR_ID, RX_INTR_ID);if (Status != XST_SUCCESS) {xil_printf("Failed intr setup\r\n");return XST_FAILURE;}// xil_printf("success intr setup\r\n");/* Disable all interrupts before setup */XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);/* Enable all interrupts */XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);/* Initialize flags before start transfer test  */TxDone = 0;RxDone = 0;Error = 0;Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR) RxBufferPtr,MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);if (Status != XST_SUCCESS) {return XST_FAILURE;}/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache* is enabled*/// flush_dcache_range((UINTPTR)TxBufferPtr, (UINTPTR)TxBufferPtr + MAX_PKT_LEN);// invalidate_dcache_range((UINTPTR)RxBufferPtr, (UINTPTR)RxBufferPtr + MAX_PKT_LEN);// unsigned int Length = XAxiDma_ReadReg(AxiDma.RegBase,0x58);// xil_printf("init Length = %x\n\r", Length);// xil_printf("NOinit:read from addr: \r\n");// u16 			wBuffer[640] 			= {0};// for(int i=0;i<20;i++)// {	// 	for(int j=0;j<32;j++)// 	{// 		wBuffer[j+i*32] = FMSH_ReadData16(RX_BUFFER_BASE,(j+i*32)*2);// 		xil_printf("0x%x ",wBuffer[j+i*32]);// 	}// 	xil_printf("\r\n");// }// xil_printf("pixel_dma_init successful\r\n");return XST_SUCCESS;
}int main()
{u32 		ulret 					= FMSH_SUCCESS;u64 		Pretime 				= 0;u64 		Curtime 				= 0;u64 		timeUsed 				= 0;DWORD 		plist1[] 				= {100, 0, 0, 0}; /* 25% for 4 partitions each */FIL 		fileinst;FIL 		*fp 					= &fileinst;FRESULT 	rc;	 							/* Result code */// FSIZE_t 	fileLen;char 		filename[32]={0};u16 		*pwbuf 					= NULL;u16 		*pwbuf_AlignStart;u16 		*pwbuf_AlignEnd;u32 		ulbw;//,ulbr;u16 		*rBuffer;u16 		*rbuf_AlignStart;int			status;int 		Length = 0;// int 		i = 0;int 		pixel_cnt = 0;global_timer_enable();/* it need to test for cache operation!* Our application use the a7_ahbram which is 128KB ocm.* include text, bss, rodat, vector, mmu table* please refer to the a7_ahbram.icf in the hello.out/output directory.*/invalidate_icache_all();icache_enable();flush_dcache_all();dcache_enable();init_platform();FMSH_WriteReg(FPS_SLCR_BASEADDR, 0x008, 0xDF0D767B);FMSH_WriteReg(FPS_SLCR_BASEADDR, 0x838, 0xf);        FMSH_WriteReg(FPS_SLCR_BASEADDR, 0x004, 0xDF0D767B);delay_ms(50);FMSH_WriteReg(0xe0029000, 0x490, 0x1);    //re-enable hp0xil_printf("\r\n--- Entering main() --- \r\n");rBuffer = malloc(FWRITE_READ_BUFFER_SIZE_MAX + 2*CONFIG_SYS_CACHELINE_SIZE);if(NULL == rBuffer){fmsh_print("rBuffer malloc err\r\n");return FMSH_FAILURE;}rbuf_AlignStart = (u16 *)(((u32)rBuffer + CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));// rbuf_AlignEnd = (u16 *)(((u32)rbuf_AlignStart +FWRITE_READ_BUFFER_SIZE_MAX+ CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));pwbuf = malloc(FWRITE_READ_BUFFER_SIZE_MAX + 2*CONFIG_SYS_CACHELINE_SIZE);if(NULL == pwbuf){fmsh_print("pwbuf malloc err\r\n");return FMSH_FAILURE;}/*由于使用了dcache,使用的buffer起始地址以cacheline size对齐,大小也需要以cacheline size对齐*/pwbuf_AlignStart = (u16 *)(((u32)pwbuf + CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));pwbuf_AlignEnd = (u16 *)(((u32)pwbuf_AlignStart +FWRITE_READ_BUFFER_SIZE_MAX+ CONFIG_SYS_CACHELINE_SIZE) & (~((u32)CONFIG_SYS_CACHELINE_SIZE - 1)));// /* 和PL做交互,通知PS状态ok */// xil_printf("Start notifying PL\r\n");FGpioPs_T 			* gpios = &g_gpios;FGpioPs_Config 		*gpio_cfgPpr;status = pixel_dma_init();if( status!= XST_SUCCESS){xil_printf("pixel_dma_init failed\r\n");}else{xil_printf("pixel_dma_init successful\r\n");}/*******************************************************************************************/
#if MANUAL_FORCE_FDISK_EN#ifdef SDMMCPS_0_DEVICE_ID/* 将MANUAL_FORCE_FDISK_EN配置为1,删除已有的分区,变成裸盘,正常流程配置为0,不走该流程*/fdisk_physicaldrive(SDMMCPS_0_DEVICE_ID);
#endif#ifdef SDMMCPS_1_DEVICE_ID/* 将MANUAL_FORCE_FDISK_EN配置为1,删除已有的分区,变成裸盘,正常流程配置为0,不走该流程*/fdisk_physicaldrive(SDMMCPS_1_DEVICE_ID);
#endifreturn FMSH_SUCCESS;
#endif/*SDMMCPS_0_DEVICE_ID,在BD中使能了sdmmc0,就会在fmsh_ps_parameters.h定义SDMMCPS_0_DEVICE_ID为0*/
#ifdef SDMMCPS_0_DEVICE_IDPretime = get_current_time();ulret = fmsh_SdEmmcInitPartFAT32(SDMMCPS_0_DEVICE_ID,1,plist1);if (ulret) {fmsh_print("fmsh_SdEmmcInitPartFAT32 sdmmc0 err\r\n");return FMSH_FAILURE;}fmsh_print("fmsh_SdEmmcInitPartFAT32 sdmmc0 success\r\n");Curtime = get_current_time();timeUsed = (Curtime - Pretime)/GTC_CLK_FREQ/1000;fmsh_print("sdmmc0 format FAT32 time Used:%lldms\r\n",timeUsed);
#endif/*SDMMCPS_1_DEVICE_ID,在BD中使能了sdmmc1,就会在fmsh_ps_parameters.h定义SDMMCPS_1_DEVICE_ID为1*/
#ifdef SDMMCPS_1_DEVICE_IDPretime = get_current_time();ulret = fmsh_SdEmmcInitPartFAT32(SDMMCPS_1_DEVICE_ID,4,plist2);if (ulret) {fmsh_print("fmsh_SdEmmcInitPartFAT32 sdmmc0 err\r\n");return FMSH_FAILURE;}Curtime = get_current_time();timeUsed = (Curtime - Pretime)/GTC_CLK_FREQ/1000;fmsh_print("sdmmc0 format FAT32 time Used:%lldms\r\n",timeUsed);
#endif#ifdef SDMMCPS_1_DEVICE_IDif(FMSH_SUCCESS != sdmmc_wr_rd_test(SDMMCPS_1_DEVICE_ID,4)){fmsh_print("sdmmc%d wr_rd_test err\r\n",SDMMCPS_1_DEVICE_ID);}
#endif//upload_bin_to_sdmmc("D:\\BOOT.bin","0:/BOOT.bin");// fmsh_print("SD test start.....\r\n");/* 和pl交互 */gpio_cfgPpr = FGpioPs_LookupConfig(FPAR_GPIOPS_2_DEVICE_ID);// xil_printf("FGpioPs_LookupConfig successful\r\n");FGpioPs_init(gpios,gpio_cfgPpr);// xil_printf("FGpioPs_init successful\r\n");FGpioPs_setDirection(gpios,0xf);// xil_printf("FGpioPs_setDirection successful\r\n");FGpioPs_writeData(gpios,0);delay_ms(1000);FGpioPs_writeData(gpios,FMSH_BIT0);delay_ms(1000);FGpioPs_writeData(gpios,0);xil_printf("start test\r\n");Pretime = get_current_time();while(1){if (RxDone){Length = pixel_dma_recv(&AxiDma,rbuf_AlignStart);if (Error) {fmsh_print("An error occurred during reception");goto Exit;}FGpioPs_writeData(gpios,FMSH_BIT0);pixel_cnt++;fmsh_print("pixel cnt is %d",pixel_cnt);memset(pwbuf_AlignStart,0x5A,FWRITE_READ_BUFFER_SIZE_MAX);memcpy(pwbuf_AlignStart,rbuf_AlignStart,Length);// 		xil_printf("\r\n");// xil_printf("NO%d:length DMA is 0x%x,first data is 0x%x 0x%x\r\n",pixel_cnt,Length,rbuf_AlignStart[0],pwbuf_AlignStart[0]);FGpioPs_writeData(gpios,0);
#ifdef SD_SAVEsprintf(filename, "TestFrame%d.bin",pixel_cnt);rc = f_open(fp, filename, FA_OPEN_APPEND|FA_READ|FA_WRITE);/*追加写入方式打开*/if (rc) {fmsh_print("Unable to open file %s: %d\r\n", filename, rc);free(pwbuf);//free(prbuf);return FMSH_FAILURE;}// fmsh_print("Success to open file %s\r\n", filename);// memset(pwbuf_AlignStart,0x5a,FWRITE_READ_BUFFER_SIZE_MAX);// rBuffer[1280] 			= {0};// memcpy(pwbuf_AlignStart,rBuffer,FWRITE_READ_BUFFER_SIZE_MAX);#if PSOC_CACHE_ENABLEflush_dcache_range((u32)pwbuf_AlignStart,(u32)pwbuf_AlignEnd);#endif// memcpy(pwbuf_AlignStart,rBuffer,FWRITE_READ_BUFFER_SIZE_MAX);// Pretime = get_current_time();		  rc= f_write(fp,(void*)pwbuf_AlignStart, FWRITE_READ_BUFFER_SIZE_MAX, &ulbw);if(rc || (FWRITE_READ_BUFFER_SIZE_MAX != ulbw)){fmsh_print("Write File To SD EMMC Card Failed[%d].\r\n",rc);f_close(fp);free(pwbuf);// free(prbuf);return FMSH_FAILURE;}		// fileLen = f_size(fp);	// fmsh_print("SD: write size[0x%x],Use time: %lldms,speed:%fKiB/s\r\n",fileLen,timeUsed,(double)(FWRITE_READ_BUFFER_SIZE_MAX)/timeUsed/1.024); rc= f_close(fp);/*关闭当前文件*/if(rc){fmsh_print("Unable to close file\r\n");free(pwbuf);// free(prbuf);return FMSH_FAILURE;}
#endifif((pixel_cnt%100) == 0){Curtime = get_current_time();timeUsed = (Curtime - Pretime)/GTC_CLK_FREQ/1000;fmsh_print("Succeed save %d frame,time used %dms\r\n",pixel_cnt,timeUsed);}// free(pwbuf);// free(prbuf);}}
Exit:DisableIntrSystem(&IntcInstance, TX_INTR_ID, RX_INTR_ID);free(pwbuf);free(rBuffer);return 0;
}

http://www.ppmy.cn/news/1268795.html

相关文章

07.Go 流程控制

流程控制是Go语言中必不可少的一部分&#xff0c;也是整个编程基础的重要一环。Go语言的流程控制语句和其他编程语言的流程控制语句有些不同&#xff0c;主要体现在Go语言没有do-while语句。Go语言常用的流程控制包括if语句、switch语句、for语句及goto语句等&#xff0c;switc…

Hasura GraphQL Engine 远程命令执行漏洞复现 [附POC]

文章目录 Hasura GraphQL Engine 远程命令执行漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现0x06 修复建议Hasura GraphQL Engine 远程命令执行漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相关技…

Java8新特性:函数式(Functional)接口

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

Excel: Python 如何干掉 VBA 系列 丙

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/FgoU8CxofwY90f3IX2Tpww 获取网络动态数据 本文开始之前夸过海口&#xff0c;说要演示一下喂养家畜的饲料动态成本&#xff0c;其实由于行业数据…

OfficeWeb365 SaveDraw 文件上传漏洞复现

0x01 产品简介 OfficeWeb365 是专注于 Office 文档在线预览及PDF文档在线预览云服务,包括 Microsoft Word 文档在线预览、Excel 表格在线预览、Powerpoint 演示文档在线预览,WPS 文字处理、WPS 表格、WPS 演示及 Adobe PDF 文档在线预览。 0x02 漏洞概述 OfficeWeb365 Sav…

element-ui以服务方式调用loading,自定义修改icon

一、以服务的方式调用Loading 除了常用的v-loading、this.$loading我们还可以以服务的方式调用。主要有以下步骤 引入Loading服务 import { Loading } from element-ui;在需要时调用 Loading.service(options);其中 options 参数为 Loading 的配置项&#xff0c;具体见下表…

《系统架构设计师教程(第2版)》第2章-计算机系统基础知识-06-系统工程

文章目录 1 系统工程概述2. 系统工程方法2.1 霍尔的三维结构2.2 切克兰德方法2.3 并行工程法2.4 综合集成法2.5 WSR系统方法3. 系统工程的生命周期3.1 各阶段1)探索性研究阶段2)概念阶段3)开发阶段4)生产阶段5)使用阶段6)保障阶段7)退役阶段3.2 生命周期方法1)计划驱动方…

前端开发中requestAnimationFrame和setInterval、setTimeout的介绍和优缺点对比

一、requestAnimationFrame() requestAnimationFrame是一种在浏览器中实现动画循环的技术&#xff0c;它通过定时器机制来周期性地调用指定的回调函数&#xff0c;以实现网页动画的效果。与传统的setInterval和setTimeout不同&#xff0c;requestAnimationFrame具有更好的浏览…