⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdhc.c

📁 ssd192Xv1 液晶驱动程序 驱动程序 彩屏液晶
💻 C
字号:
#include "sdhc.h"
#include "sdhcmap.h"
#include "sdhcbase.h"
//#include "hw.h"
#include "utils.h"
#define debug myprintf
static int isSDHCInitialized=0;

//SDHC_T* theSDHCHandle;
int g_theblklen;//block length
int g_thewidth;//width: 1 or 4 data wire 
char g_isAUTOCMD12; //if AUTOCMD12 is used, no need to send abort after transfer
unsigned short g_rca; //similar to an address
//#define debug(fmt,arg...) printk(fmt, ##arg)
DEVICE_OP sdhc_dev_op={
	read: sdhc_dev_read,
	write: sdhc_dev_write,
};

void initSDHC()
{
//	CSD_T	theCSD;//	CID_T	theCID;//	SCR_T	theSCR;//	unsigned long theCardType;	unsigned long status;
	int dividerCode;
	isSDHCInitialized=1;
//	printk("init SDHC********************\n");/*//        theSDHCHandle=(SDHC_T*)SDHC_MODULE_BASE;//mapping to register	printk("theSDHCHandle=0x%X\n",theSDHCHandle);
	printk("u32DMAAdr         :0x%x\n",&theSDHCHandle->u32DMAAddr);	printk("u16BlkSize        :0x%x\n",&theSDHCHandle->u16BlkSize);	printk("u16BlkCount       :0x%x\n",&theSDHCHandle->u16BlkCount);	printk("u32Arg            :0x%x\n",&theSDHCHandle->u32Arg);	printk("u16TrnsfrMode     :0x%x\n",&theSDHCHandle->u16TrnsfrMode);	printk("u16Cmd            :0x%x\n",&theSDHCHandle->u16Cmd);	printk("a32Rsp            :0x%x\n",theSDHCHandle->a32Rsp);	printk("u8DataPort        :0x%x\n",&theSDHCHandle->u8DataPort);	printk("a8Rsvd1           :0x%x\n",theSDHCHandle->a8Rsvd1);	printk("u32PrsntState     :0x%x\n",&theSDHCHandle->u32PrsntState);	printk("u8HstCntl         :0x%x\n",&theSDHCHandle->u8HstCntl);	printk("u8PwrCntl         :0x%x\n",&theSDHCHandle->u8PwrCntl);	printk("u8BlkGapCntl      :0x%x\n",&theSDHCHandle->u8BlkGapCntl);	printk("u8WkupCntl        :0x%x\n",&theSDHCHandle->u8WkupCntl);	printk("u8ClkCntl         :0x%x\n",&theSDHCHandle->u8ClkCntl);	printk("u8ClkDiv          :0x%x\n",&theSDHCHandle->u8ClkDiv);	printk("u8ToutCntl        :0x%x\n",&theSDHCHandle->u8ToutCntl);	printk("u8SwReset         :0x%x\n",&theSDHCHandle->u8SwReset);	printk("u16NrmIntrStatus  :0x%x\n",&theSDHCHandle->u16NrmIntrStatus);	printk("u16ErrIntrStatus  :0x%x\n",&theSDHCHandle->u16ErrIntrStatus);	printk("u16NrmIntrStatusEn:0x%x\n",&theSDHCHandle->u16NrmIntrStatusEn);	printk("u16ErrIntrStatusEn:0x%x\n",&theSDHCHandle->u16ErrIntrStatusEn);	printk("u16NrmIntrSignalEn:0x%x\n",&theSDHCHandle->u16NrmIntrSignalEn);	printk("u16ErrIntrSignalEn:0x%x\n",&theSDHCHandle->u16ErrIntrSignalEn);	printk("u16ACMD12ErrStatus:0x%x\n",&theSDHCHandle->u16ACMD12ErrStatus);	printk("u16Rsvd2          :0x%x\n",&theSDHCHandle->u16Rsvd2);	printk("u32Capabilities   :0x%x\n",&theSDHCHandle->u32Capabilities);	printk("u32CapRsvd        :0x%x\n",&theSDHCHandle->u32CapRsvd);	printk("u32MaxCurrCap     :0x%x\n",&theSDHCHandle->u32MaxCurrCap);	printk("u32MaxCurrCapRsvd :0x%x\n",&theSDHCHandle->u32MaxCurrCapRsvd);	printk("u32Rsvd3          :0x%x\n",theSDHCHandle->u32Rsvd3);	printk("u16SlotIntrStatus :0x%x\n",&theSDHCHandle->u16SlotIntrStatus);	printk("u16HCVer          :0x%x\n",&theSDHCHandle->u16HCVer);*/	g_theblklen=512;	//block size = 512 byte
	g_thewidth=1;//g_thewidth=4;	//4 wire or 1 wire [only 1 wire for MMC]	g_isAUTOCMD12=1;//use AUTOCMD12 as default instead of send abort at the end of transfer

	sdhc_init(&g_rca);	
	sdhc_set_buswidth(g_thewidth);
	sdhc_set_blklen(g_theblklen);	
	dividerCode=0x1;	//printk("Divider Code=%X\n",dividerCode);	clock_cntl (0x4,dividerCode,1);	decode_r1(status);
}

#define checkInitialized()	{	if(!isSDHCInitialized)	{	initSDHC();	}	}

int sdhc_set_block_length(unsigned long blklen)
{
	checkInitialized();
	g_theblklen=blklen; //block size = 512 byte
	return sdhc_set_blklen(g_theblklen);}
int sdhc_get_block_length()
{
	return g_theblklen;
}

unsigned long sdhc_get_card_type()
{
	return _sdhc_get_card_type();
}
unsigned long sdhc_get_card_capacity()
{
	return _sdhc_get_card_capacity();
}

int sdhc_dma_read_single(unsigned long SDByteAddr, unsigned char *blkbuf)
{
	checkInitialized();

	int nblk=1;//0:single block transfer
	int flag=(RWF_DMA) |(g_isAUTOCMD12? RWF_AUTOCMD12:0);
	INT32 memOffset=ssd_mem_malloc(g_theblklen);	if(memOffset>=0)	{		int i,error;		error=sdhc_read_ex (SDByteAddr, memOffset, g_theblklen, nblk,flag, 0);		for(i=0;i<g_theblklen;i++)		{			blkbuf[i]=SSD_MEMRB(memOffset+i);		}		ssd_mem_free(memOffset);		return error;	}	else	{		return -1;//error	}}

int sdhc_dma_read_multiple(unsigned long SDByteAddr, unsigned char *blkbuf, int nblk)
{
	checkInitialized();
	//myprintf("SDByteAddress = 0x%x.\n\r", SDByteAddr);	int flag=(RWF_DMA) |(g_isAUTOCMD12? RWF_AUTOCMD12:0);
	INT32 memOffset=ssd_mem_malloc(g_theblklen);	//myprintf("Memory offset = 0x%x.\n\r", memOffset);	if(memOffset>=0)	{		int i,error;		int blkIndex=0;		error=0;				for(blkIndex=0;blkIndex<nblk && !error; blkIndex++)		{			int bufOffset=blkIndex*g_theblklen;			error=sdhc_read_ex (SDByteAddr+bufOffset, memOffset, g_theblklen, 1,flag, 0);//1 block each time			for(i=0;i<g_theblklen;i++)			{				blkbuf[i+bufOffset]=SSD_MEMRB(memOffset+i);			}		}		ssd_mem_free(memOffset);		return error;	}	else	{		return -1;	}	//return sdhc_read(theSDHCHandle,SDByteAddr,blkbuf,g_theblklen,nblk,flag,0);}

int sdhc_dma_read_multiple_to_memory(unsigned long SDByteAddr, int memOffset, int nblk)
{
	checkInitialized();

	int flag=(RWF_DMA) |(g_isAUTOCMD12? RWF_AUTOCMD12:0)| RWF_NOREAD;
	return sdhc_read_ex (SDByteAddr, memOffset, g_theblklen, nblk,flag, 0);}


int sdhc_dma_write_single(unsigned long SDByteAddr, unsigned char *blkbuf)
{
	checkInitialized();

	int nblk=1;//0: single block transfer
	int flag=(RWF_DMA) |(g_isAUTOCMD12? RWF_AUTOCMD12:0);
	INT32 memOffset=ssd_mem_malloc(g_theblklen);	if(memOffset>=0)	{		int i,error;		int blkIndex=0;		error=0;				for(i=0;i<g_theblklen;i++)		{			SSD_MEMWB(memOffset+i,blkbuf[i]);		}		error=sdhc_write_ex (SDByteAddr, memOffset, g_theblklen, 1,flag, 0);//1 block each time		ssd_mem_free(memOffset);		return error;	}	else	{		return -1;	}	//return sdhc_write (theSDHCHandle,SDByteAddr,blkbuf, g_theblklen,nblk, flag,0);}

int sdhc_dma_write_multiple(unsigned long SDByteAddr, unsigned char *blkbuf, int nblk)
{
	checkInitialized();

	int flag=(RWF_DMA) |(g_isAUTOCMD12? RWF_AUTOCMD12:0);
	INT32 memOffset=ssd_mem_malloc(g_theblklen);	if(memOffset>=0)	{		int i,error;		int blkIndex=0;		error=0;				for(blkIndex=0;blkIndex<nblk && !error; blkIndex++)		{			int bufOffset=blkIndex*g_theblklen;			for(i=0;i<g_theblklen;i++)			{				SSD_MEMWB(memOffset+i,blkbuf[i+bufOffset]);			}			error=sdhc_write_ex (SDByteAddr+bufOffset, memOffset, g_theblklen, 1,flag, 0);//1 block each time		}		ssd_mem_free(memOffset);		return error;	}	else	{		return -1;	}	//return sdhc_write (theSDHCHandle,SDByteAddr,blkbuf, g_theblklen,nblk, flag,0);}

int sdhc_dma_write_multiple_from_memory(unsigned long SDByteAddr, int memOffset, int nblk)
{
	checkInitialized();

	int flag=(RWF_DMA) |(g_isAUTOCMD12? RWF_AUTOCMD12:0)|RWF_NOFILL;
	return sdhc_write_ex (SDByteAddr,memOffset, g_theblklen,nblk, flag,0);}

int sdhc_pio_read_single(unsigned long SDByteAddr, unsigned char *blkbuf)
{
	checkInitialized();

	int nblk=1;//0:single block transfer
	int flag=(g_isAUTOCMD12? RWF_AUTOCMD12:0 );
	//return sdhc_read(theSDHCHandle,SDByteAddr,blkbuf,g_theblklen,nblk,flag,0);}

int sdhc_pio_read_multiple(unsigned long SDByteAddr, unsigned char *blkbuf, int nblk)
{
	checkInitialized();

	int flag=(g_isAUTOCMD12? RWF_AUTOCMD12:0 );
	//return sdhc_read(theSDHCHandle,SDByteAddr,blkbuf,g_theblklen,nblk,flag,0);}

int sdhc_pio_write_single(unsigned long SDByteAddr, unsigned char *blkbuf)
{
	checkInitialized();

	int nblk=1;
	int flag=(g_isAUTOCMD12? RWF_AUTOCMD12:0);
	//return sdhc_write (theSDHCHandle,SDByteAddr,blkbuf, g_theblklen,nblk, flag,0);}

int sdhc_pio_write_multiple(unsigned long SDByteAddr, unsigned char *blkbuf, int nblk)
{
	checkInitialized();

	int flag=(g_isAUTOCMD12? RWF_AUTOCMD12:0);
	//return sdhc_write (theSDHCHandle,SDByteAddr,blkbuf, g_theblklen,nblk, flag,0);}

int sdhc_reset_all ()
{
	checkInitialized();
	//reset data
	//reset cmd
	sdhc_reset ( SW_RESET_ALL);}

int sdhc_set_buswidth (int width)
{	
	checkInitialized();
	g_thewidth=width;	//4 wire or 1 wire [only 1 wire for MMC]
	return sdhc_set_width(g_rca,g_thewidth);}

int sdhc_get_buswidth()
{
	return g_thewidth;
}

int sdhc_set_autocmd12(int isOn)
{
	checkInitialized();
	g_isAUTOCMD12=isOn;//use AUTOCMD12 as default instead of send abort at the end of transfer
	return 0;
}

UINT32 sdhc_dev_read_with_mcu_address(UINT32 SDOffset, UINT8 *buffer, UINT32 byteSize)
{
	int blockLen=sdhc_get_block_length();
	int numOfFullBlock=byteSize/blockLen;
	int residualSize=byteSize;
	int retCode=0;

	INT32 memOffset=ssd_mem_malloc(blockLen);
	if(memOffset<0)
	{
		debug("memory not enough\n");
		return 0;
	}

	int DataStartInsideBlock=SDOffset%blockLen;
	int SDOffsetToRead=SDOffset-DataStartInsideBlock;
	int bufferIndex=0;

	while(residualSize>0)
	{		
		int i;
		if(retCode=sdhc_dma_read_multiple_to_memory(SDOffsetToRead, memOffset, 1))
		{
			break;
		}

		for(i=0;i<blockLen && residualSize;i++)
		{			
			buffer[bufferIndex++]=*(unsigned char*)(SSD_MAP_MEM+memOffset+DataStartInsideBlock+i);
			residualSize--;
		}
		SDOffsetToRead+=blockLen;
		DataStartInsideBlock=0;
	}

	ssd_mem_free(memOffset);
	if(retCode)
		return 0;
	else
		return byteSize;	
}

UINT32 sdhc_dev_read_with_1923_address(UINT32 SDOffset, UINT8 *buffer, UINT32 byteSize)
{
	int blockLen=sdhc_get_block_length();
	int numOfFullBlock=byteSize/blockLen;
	int residualSize=byteSize;
	int retCode=0;
	int memOffset=(int)buffer;
	memOffset-=SSD_MAP_MEM;

	if(numOfFullBlock>0)
	{
		retCode=sdhc_dma_read_multiple_to_memory(SDOffset, memOffset, numOfFullBlock);
		residualSize-=numOfFullBlock*blockLen;
	}

	if(!retCode && residualSize>0)
	{
		int i;
		INT32 tempMem=ssd_mem_malloc(512);//one block
		if(tempMem<0)
		{
			return -1;
		}

		retCode=sdhc_dma_read_multiple_to_memory(SDOffset+numOfFullBlock*blockLen, tempMem, 1);
		
		int tempMemBase=SSD_MAP_MEM+tempMem;

		for(i=0;i<residualSize;i++)
		{
			buffer[numOfFullBlock*blockLen+i]=*(unsigned char*)(tempMemBase+i);
		}
		ssd_mem_free(tempMem);
	}

	if(retCode)
		return 0;
	else
		return byteSize;
}

UINT32 sdhc_dev_write_with_mcu_address(UINT32 SDOffset, UINT8 *buffer, UINT32 byteSize)
{
	int i;
	int blockLen=sdhc_get_block_length();
	int numOfFullBlock=byteSize/blockLen;
	int residualSize=byteSize;
	int retCode=0;

	INT32 memOffset=ssd_mem_malloc(blockLen);
	if(memOffset<0)
	{
		debug("memory not enough\n");
		return 0;
	}

	int DataStartInsideBlock=SDOffset%blockLen;
	int SDOffsetToRead=SDOffset-DataStartInsideBlock;
	int bufferIndex=0;

	while(residualSize>0)
	{		

		int i;
		//1.if the data is start inside a block or the data is not a full block
		//read out the data block first
		if(DataStartInsideBlock || residualSize<blockLen)
		{
			debug("read out the data\n");
			if(retCode=sdhc_dma_read_multiple_to_memory(SDOffsetToRead, memOffset, 1))
			{
				break;
			}
		}

		//2. modified the data block
		for(i=DataStartInsideBlock;i<blockLen && residualSize;i++)
		{			
			*(unsigned char*)(SSD_MAP_MEM+memOffset+i)=buffer[bufferIndex++];
			residualSize--;
		}

		//3. write back the data block
		if(retCode=sdhc_dma_write_multiple_from_memory(SDOffsetToRead, memOffset, 1))
		{
			debug("sdhc_dma_write_multiple_from_memory() error =%d\n",retCode);
			break;
		}
		SDOffsetToRead+=blockLen;
		DataStartInsideBlock=0;
	}

	ssd_mem_free(memOffset);
	if(retCode)
		return 0;
	else
		return byteSize;	

}

UINT32 sdhc_dev_write_with_1923_address(UINT32 SDOffset, UINT8 *buffer, UINT32 byteSize)
{
	int blockLen=sdhc_get_block_length();
	int numOfFullBlock=byteSize/blockLen;
	int residualSize=byteSize%blockLen;
	int retCode=0;
	int memOffset=(int)buffer;
	memOffset-=SSD_MAP_MEM;

	if(byteSize>0)
	{
		retCode=sdhc_dma_write_multiple_from_memory(SDOffset, memOffset, numOfFullBlock+residualSize?1:0);
	}
/*
	if(!retCode && residualSize>0)
	{
		int i;
		INT32 tempMem=ssd_mem_malloc(512);//one block
		if(tempMem<0)
		{
			return -1;
		}

		//1. read back
		retCode=sdhc_dma_read_multiple_to_memory(SDOffset+numOfFullBlock*blockLen,tempMem,1);
		if(!retCode)
		{
			int tempMemBase=SSD_MAP_MEM+tempMem;

			//2. modified the data
			for(i=blockLen-residualSize;i<blockLen;i++)
			{
				buffer[numOfFullBlock*blockLen+i]=*(unsigned char*)(tempMemBase+i);
			}
			//3.write back to SD card
			retCode=sdhc_dma_write_multiple_from_memory(SDOffset+numOfFullBlock*blockLen, tempMem, 1);
		}
		
		ssd_mem_free(tempMem);
	}
*/
	if(retCode)
		return 0;
	else
		return byteSize;

}

UINT32 sdhc_dev_read(UINT32 SDOffset, UINT8 *buffer, UINT32 byteSize)
{
	int blockLen=sdhc_get_block_length();
	int retCount=0;

	if(buffer<SSD_MAP_MEM || buffer>SSD_MAP_MEM+512*1024 || (int)buffer%512 || SDOffset%blockLen)
	{
		retCount= sdhc_dev_read_with_mcu_address(SDOffset,buffer,byteSize);
	}
	else
	{
		retCount= sdhc_dev_read_with_1923_address(SDOffset,buffer,byteSize);
	}

	return retCount;
}
UINT32 sdhc_dev_write(UINT32 SDOffset, UINT8 *buffer, UINT32 byteSize)
{
	int blockLen=sdhc_get_block_length();
	int retCount=0;
	
	if(buffer<SSD_MAP_MEM || buffer>SSD_MAP_MEM+512*1024 || (int)buffer%512 || SDOffset%blockLen)
	{
		retCount= sdhc_dev_write_with_mcu_address(SDOffset,buffer,byteSize);
	}
	else
	{
		retCount= sdhc_dev_write_with_1923_address(SDOffset,buffer,byteSize);
	}
	return retCount;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -