复旦微用AXIDMA接收原始图像

参考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.mzph.cn/news/219537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS 7 部署frp穿透内网

本文将介绍如何在CentOS 7.9上部署frp&#xff0c;并通过示例展示如何配置和测试内网穿透。 文章目录 &#xff08;1&#xff09;引言&#xff08;2&#xff09;准备工作&#xff08;4&#xff09;frps服务器端配置&#xff08;5&#xff09;frpc客户端配置&#xff08;6&#…

【Linux】进程和环境变量

我们启动一个软件&#xff0c;本质就是启动一个进程 在Linux下&#xff0c;运行一条命令&#xff0c;运行的时候&#xff0c;其实就是在系统层面创建了一个进程 而Linux系统管理大量进程则是先描述&#xff0c;再组织 进程 对应的代码和数据 进程等对应的PCB结构体 PCB包含了…

深度优先搜索LeetCode979. 在二叉树中分配硬币

给你一个有 n 个结点的二叉树的根结点 root &#xff0c;其中树中每个结点 node 都对应有 node.val 枚硬币。整棵树上一共有 n 枚硬币。 在一次移动中&#xff0c;我们可以选择两个相邻的结点&#xff0c;然后将一枚硬币从其中一个结点移动到另一个结点。移动可以是从父结点到…

postman接口测试系列: 时间戳和加密

在使用postman进行接口测试的时候&#xff0c;对于有些接口字段需要时间戳加密&#xff0c;这个时候我们就遇到2个问题&#xff0c;其一是接口中的时间戳如何得到&#xff1f;其二就是对于现在常用的md5加密操作如何在postman中使用代码实现呢&#xff1f; 下面我们以一个具体的…

【ZeroMQ(ZMQ)】高速并发通信框架学习笔记(C风格、C++风格都有哦)

目录 官方文档&#xff1a; ZeroMQ An open-source universal messaging library 前言 ☘️ ZeroMQ——基于消息队列模式的Socket库 框架提供的套接字可以满足在多种协议之间传输原子信息&#xff0c;如线程间、进程间、TCP、广播等。 ZMQ将消息通信分成 4 种模型&#xff0c…

JavaEE之多线程编程:2.创建线程及Thread类常见方法(超全!!!)

一、创建线程 Java中创建线程的写法有很多种&#xff01;&#xff01;&#xff01;这里介绍其中5种。 方法1&#xff1a;继承Thread类&#xff0c;重写run 创建一个类&#xff0c;让这个类继承自Thread父类&#xff0c;再重写我们的run方法就可以了。 使用Thread类&#xff…

MYsql第三次作业

目录 问题&#xff1a; 解答 1.查询student表的所有记录 2.查询student表的第2条到4条记录 3.从student表查询所有学生的学号&#xff08;id&#xff09;、姓名&#xff08;name&#xff09;和院系&#xff08;department&#xff09;的信息 4.从student表中查询计算机系和…

智能优化算法应用:基于鸽群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鸽群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鸽群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鸽群算法4.实验参数设定5.算法结果6.参考文献7.MA…

EdgeYOLO: anchor-free,边缘部署友好

简体中文 1 Intro 2 Updates 3 Coming Soon 4 Models 5 Quick Start \quad 5.1 setup

物奇平台MIC配置与音频通路关系

物奇平台MIC配置与音频通路关系 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;可加我微信hezkz17, 本群提供音频技术答疑服务&#xff0c;群赠送语音信号处理降噪算法&#xff0c;蓝牙耳机音频&#xff0c;DSP音频项目核心开发资料, 1 255代表无效&am…

uni-app 一些实用的页面模板

时间倒计时 <!-- 时间倒计时 --> <template><view class"container"><view class"flex-row time-box"><view class"time-item">{{ laveTimeList[0] }}</view><text>天</text><view class&qu…

Java笔记草稿——已完成

导航&#xff1a; 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/黑马旅游/谷粒商城/学成在线设计模式面试题汇总性能调优/架构设计源码-CSDN博客 推荐学习视频&#xff1a; 黑马程序员全套Java教程_哔哩哔哩 尚硅谷Java入门视频教程_哔哩哔哩 目录 零…

[BUUCTF 2018]Online Tool1

提示 利用nmap上传文件 首先进行代码分析&#xff1a; 首先是进行判断http信息头里是否在HTTP_X_FORWARDED_FOR并且是否有参数 $_SERVER[“HTTP_X_FORWARDED_FOR”] 的值才是客户端真正的IP&#xff08;如果是多层代理&#xff0c;该值可能是由客户端真正IP和多个代理服务…

二十五、图形视图框架

二十五、图形视图框架 我们将要用到三个类&#xff0c;QGraphicsView&#xff08;视图类&#xff09;、QGraphicsScene&#xff08;场景类&#xff09;、QGraphicsItem&#xff08;图元类&#xff09;。 QGraphicsView&#xff08;视图类&#xff09; 继承QWidget类&#xf…

玩转Docker(一):容器生态系统

文章目录 一、核心技术二、平台技术三、支持技术 本文结构如下&#xff1a; 一、核心技术 容器核心技术是指能够让Container在host上运行起来的那些技术。 &#xff08;1&#xff09;容器规范 容器不光是Docker&#xff0c;还有其他容器&#xff0c;比如CoreOS的rkt。为了保证…

网络推理之深度学习推理框架

如何选择深度学习推理框架&#xff1f; PyTorch vs LibTorch&#xff1a;网络推理速度谁更快&#xff1f; 高质量C进阶[2]&#xff1a;如何让线性代数加速1000倍&#xff1f; TensorRT: ONNX:

微服务--07--Sentienl中使用的限流算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Sentienl中使用的限流算法1、计数器固定窗口算法2、计数器滑动窗口算法----&#xff08;默认&#xff09;3、漏桶算法----&#xff08;排队等待&#xff09;4、令牌…

node.js 启一个前端代理服务,代码直接改一改拿来用

文章目录 前言一、分析技术二、操作步骤2.1、下载依赖2.2、创建一个 serve.js 文件2.3、js 文件中写入以下代码 三、运行&#xff1a; node serve四、结果展示五、总结六、感谢 前言 有时候我们需要做一些基础的页面时&#xff0c;在研发过程中需要代理调用接口避免浏览器跨域…

AI全栈大模型工程师(二十六)如何选择 GPU 和云服务厂商

&#x1f4a1; 这节课会带给你 如何选择 GPU 和云服务厂商&#xff0c;追求最高性价比 如何部署自己 fine-tune 的模型&#xff0c;向业务提供高可用推理服务 如何控制内容安全&#xff0c;做好算法备案&#xff0c;确保合规 开始上课&#xff01; 硬件选型 当我们为模型训练及…

电子学会C/C++编程等级考试2022年12月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:漫漫回国路 2020年5月,国际航班机票难求。一位在美国华盛顿的中国留学生,因为一些原因必须在本周内回到北京。现在已知各个机场之间的航班情况,求问他回不回得来(不考虑转机次数和机票价格)。 时间限制:1000 内存限制:655…