参考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;
}