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

📄 sdreg.c

📁 ssd192Xv1 液晶驱动程序 驱动程序 彩屏液晶
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (rsp[0] & (R1_STAT_ERR | R1_STAT_BLK_LEN_ERR))	{		db ("sdhc_set_blklen: Set Block Length rejected by card\n\r");		decode_r1 (rsp[0]);		return -1;	}	return 0;}int sdhc_set_width (unsigned short g_rca, int width){	unsigned long rsp[4];	rsp[0] = (g_rca << 16) | 0x0000FFFFUL;	rsp[1] = 0xFFFFFFFCUL | (width == 1 ? 0UL : 2UL);	// 2'b00=1-bit, 2'b10=4-bit	if (send_app_cmd (ACMD_SET_BUS_WIDTH, NORMAL, R48, 1, 1, rsp) < 0)	{		db ("sdhc_set_width: Set Width (ACMD6) failed\n\r");		return -1;	}	if (rsp[0] & R1_STAT_ERR)	{		db ("sdhc_set_width: Set Width rejected by card\n\r");		decode_r1 (rsp[0]);		return -1;	}	if (width == 4)	{		SSD_REGWB(REG_u8HstCntl, SSD_REGRB(REG_u8HstCntl) | HCR_TRANS_WIDTH);	        myprintf("Host Control Register Value is %x , and HCR_TRANS_WIDTH is %x\n\r",SSD_REGRB(REG_u8HstCntl),HCR_TRANS_WIDTH);	        myprintf("SET DATA BUS WIDTH IS 4 \n\r");	}	else if (width == 1)		SSD_REGWB(REG_u8HstCntl, SSD_REGRB(REG_u8HstCntl) & ~HCR_TRANS_WIDTH);	return 0;}//// start of mostly sdio functions//#define	IO_READ_DIRECT(fn,addr)	((((fn) & 0x07UL) << 28) | ((addr) << 9))#define IO_WRITE_DIRECT(fn,raw,addr,data) ((1UL << 31) | (((fn) & 0x07UL) << 28) |\	       				((raw) ? (1 << 27) : 0) |\					((addr) << 9) |\					((data) & 0xFFUL))#define IO_RW_EXT_WRITE		BIT(31)#define IO_RW_EXT_MULTIBLK	BIT(27)#define IO_RW_EXT_OPCODE	BIT(26)#define IO_READ_EXT(fn,flags,addr,nblk,blklen)	\		((((fn) & 0x7) << 28) | \		(RW_MULTIBLK_EN((flags)) ? ((nblk == 0) ? 0 : IO_RW_EXT_MULTIBLK) : 0) |\		(RW_IO_INCR_EN((flags)) ? IO_RW_EXT_OPCODE : 0) |\		(((addr) & 0x1FFFF) << 9) |\		((((nblk) == 0) ? (blklen) : \		  	(((nblk) > 0) ? (nblk) : 0)) & 0x1FF))			#define IO_WRITE_EXT(fn,flags,addr,nblk,blklen)	\		(IO_RW_EXT_WRITE | \		(((fn) & 0x7) << 28) | \		(RW_MULTIBLK_EN((flags)) ? ((nblk == 0) ? 0 : IO_RW_EXT_MULTIBLK) : 0) |\		(RW_IO_INCR_EN((flags)) ? IO_RW_EXT_OPCODE : 0) |\		(((addr) & 0x1FFFF) << 9) |\		((((nblk) == 0) ? (blklen) : \		  	(((nblk) > 0) ? (nblk) : 0)) & 0x1FF))int io_reset () {	unsigned long rsp[4];	rsp[0] = IO_WRITE_DIRECT (0, 0, CCCR_ASR, CCCR_ASR_RESET);	if (send_cmd_SD (CMD_IO_RW_DIRECT, NORMAL, R0, 0, 0, 0, rsp) < 0) {		//db ("IO reset failed\n\r");		return -1;	}	return 0;}int io_write_byte (int fn, int raw, unsigned long addr, unsigned char data){	unsigned long rsp[4];	//db ("io_write_byte: fn=%d, raw=%d, addr=0x%08lx, data=0x%02x\n\r", fn, raw, addr, data);	rsp[0] = IO_WRITE_DIRECT (fn, raw, addr, data);	if (send_cmd_SD (CMD_IO_RW_DIRECT, NORMAL, R48, 0, 1, 1, rsp) < 0) {		//db ("SDIO: io_write_byte failed\n\r");		return -1;	}	else if (rsp[0] & R5_STAT_ERR) {		decode_r5 (rsp[0]);		return -1;	}	return raw ? rsp[0] & 0xFFUL : 0;}int io_read_byte (int fn, unsigned long addr, unsigned char *data){	unsigned long rsp[4];	rsp[0] = IO_READ_DIRECT (fn, addr);	if (send_cmd_SD (CMD_IO_RW_DIRECT, NORMAL, R48, 0, 1, 1, rsp) < 0) {		//db ("SDIO: io_read_byte (fn=%d, addr=0x%08lx) failed\n\r", fn, addr);		return -1;	}	else if (rsp[0] & R5_STAT_ERR) {		//db ("SDIO: io_read_byte (fn=%d, addr=0x%08lx) failed\n\r", fn, addr);		decode_r5 (rsp[0]);		return -1;	}	*data = (unsigned char) (rsp[0] & 0xffUL);	//db ("io_read_byte: fn=%d, addr=0x%08lx data=0x%02x\n\r", fn, addr, *data); 	return 0;}int io_write_direct (int fn, unsigned long addr, unsigned char *data, int len){	int i;	unsigned long rsp[4];	//db ("io_write_direct: fn=%d, raw=0, addr=0x%08lx len=%d\n\r", fn, addr, len);	for (i = 0; i < len; i++) {		rsp[0] = IO_WRITE_DIRECT (fn, 0, addr+i, data[i]);		if (send_cmd_SD (CMD_IO_RW_DIRECT, NORMAL, R48, 0, 1, 1, rsp) < 0) {			//db ("SDIO: direct write failed at offset=0x%x", i);			return -1;		}		else if (rsp[0] & R5_STAT_ERR) {			decode_r5 (rsp[0]);			return -1;		}	}	return 0;}int io_read_direct (int fn, unsigned long addr, unsigned char *data, int len){	int i;	unsigned long rsp[4];	//db ("io_read_direct: fn=%d, addr=0x%08lx len=%d\n\r", fn, addr, len);	for (i = 0; i < len; i++) {		rsp[0] = IO_READ_DIRECT (fn, addr+i);		if (send_cmd_SD (CMD_IO_RW_DIRECT, NORMAL, R48, 0, 1, 1, rsp) < 0) {			//db ("SDIO: direct read failed at offset=0x%x\n\r", i);			return -1;		}		else if (rsp[0] & R5_STAT_ERR) {			decode_r5 (rsp[0]);			return -1;		}		else			data[i] = (unsigned char) (rsp[0] & 0xffUL);	}	return 0;}// end of mostly sdio functions/* rw flags * byte0 - for sdhc hw options, eg. dma & autocmd12 * byte1 - reserved * byte2 - for rd api * byte3 - for wr api */#define RWF_DMA		0x00000001UL#define RWF_AUTOCMD12	0x00000002UL#define RWF_MULTIBLK	0x00000004UL	// set only for IO && when Multi block transfer is enabled#define RWF_IO_INCR	0x00000008UL	// set only for IO, OP Code bit in IO_RW_EXTENDED, 0=fixed,1=incr#define RWF_IO		0x00000010UL	// set for IO and cleared for Memory Read/Write#define RWF_CONT	0x00000100UL	// not used#define RWF_END		0x00000200UL	// not used#define RWF_CURR_BUF	0x00000400UL	// used when RW_NOFILL_EN or RW_NOREAD_EN is enabled to signal selected buffer#define RWF_SYNC	0x00000800UL	// used by interrupt routines#define RWF_BYTECMP	0x00010000UL#define RWF_BLKCMP	0x00020000UL#define RWF_FILESAVE	0x00040000UL#define RWF_NOREAD	0x00080000UL#define RWF_BYTEFILL	0x01000000UL#define RWF_BLKFILL	0x02000000UL#define RWF_FILEFILL	0x04000000UL#define RWF_NOFILL	0x08000000UL// for both write & read#define RW_DMA_EN(x)		((x) & RWF_DMA)#define RW_AUTOCMD12_EN(x)	((x) & RWF_AUTOCMD12)#define RW_MULTIBLK_EN(x)	((x) & RWF_MULTIBLK)	// checked for SDIO only#define RW_IO_INCR_EN(x)	((x) & RWF_IO_INCR)	// checked for SDIO only#define RW_IO_EN(x)		((x) & RWF_IO)		// checked for memory or SDIO access// for continuous mode write via internal memory (RW_NOFILLE_EN=1)#define RW_CONT_EN(x)		((x) & RWF_CONT)#define RW_END_EN(x)		((x) & RWF_END)#define RW_CURR_BUF(x)		((x) & RWF_CURR_BUF)#define RW_SYNC_EN(x)		((x) & RWF_SYNC)// for read_data#define RW_BYTECMP_EN(x)	((x) & RWF_BYTECMP)#define RW_BLKCMP_EN(x)		((x) & RWF_BLKCMP)#define RW_FILESAVE_EN(x)	((x) & RWF_FILESAVE)#define RW_NOREAD_EN(x)		((x) & RWF_NOREAD)// for write_data#define RW_BYTEFILL_EN(x)	((x) & RWF_BYTEFILL)#define RW_BLKFILL_EN(x)	((x) & RWF_BLKFILL)#define RW_FILEFILL_EN(x)	((x) & RWF_FILEFILL)#define RW_NOFILL_EN(x)		((x) & RWF_NOFILL)/*int fifo_reset (SDHCEXT_T *ext){	int i;	ext->u16FIFOCntl |= SWAP16(0x0001);	for (i = 0; i < MAX_WAIT; i++) {	       	delay_us (1);		if (!(ext->u16FIFOCntl & SWAP16(0x0001)))			break;	}	return 0;}int fifo_readback (SDHCEXT_T *ext, int n, unsigned char *data, int len){#define FIFOCNTL_RST	BIT16(0)#define FIFOCNTL_RDBK	BIT16(1)#define FIFOCNTL_SYSBUFSEL	BIT16(8)#define FIFOCNTL_SIBUFSEL	BIT16(9)	int i;	// turn on fifo readback bit in the extension register	// select the sys_buf_sel 0=fifo0, 1=fifo1	// copy data from fifo upto len bytes into g_data	//db ("fifo_readback: status before reset: SYSBUFSEL=%d, SIBUFSEL=%d\n\r", 	//		SWAP16(ext->u16FIFOCntl & FIFOCNTL_SYSBUFSEL) ? 1:0,	//		SWAP16(ext->u16FIFOCntl & FIFOCNTL_SIBUFSEL) ? 1:0);	sdhc_reset (SW_RESET_DATA);	sdhc_reset (SW_RESET_CMD);		ext->u16FIFOCntl |= FIFOCNTL_RST;	for (i = 0; i < MAX_WAIT; i++) {	       	delay_us (1);		if (!(ext->u16FIFOCntl & FIFOCNTL_RST))			break;	}	ext->u16FIFOCntl |= FIFOCNTL_RDBK;	if (n)		ext->u16FIFOCntl |= FIFOCNTL_SYSBUFSEL;	else		ext->u16FIFOCntl &= ~FIFOCNTL_SYSBUFSEL;	//db ("fifo_readback: FIFOCNTL = 0x%04x, SYSBUFSEL=%d\n\r", SWAP16(ext->u16FIFOCntl), n);	for (i = 0; i < len; i++)		*data++ = SSD_REGRB(REG_u8DataPort);		ext->u16FIFOCntl &= ~FIFOCNTL_RDBK;	sdhc_reset (SW_RESET_DATA);	sdhc_reset (SW_RESET_CMD);		return 0;}*/#ifndef __KERNEL__  //kevin #ifdef __KERNEL__void sdhc_interrupt (void){	// interrupts are turned off here	// interrupts are enabled in sdhc_write_th	SSD_REGWW(REG_u16NrmIntrSignalEn , 0);	SSD_REGWW(REG_u16ErrIntrSignalEn , 0);	return;}int sdhc_read_ex ( 		unsigned long addr, 		unsigned long data, // dma start address in amazon memory		int blklen, 		long nblk, 		unsigned long flags, 		void *param){	int	error = 0;	unsigned short event = 0;	unsigned short nisr = 0;	unsigned short blkcnt = 0;	unsigned long tmp;	unsigned long rsp[4];	unsigned long blks_per_buf = 0;		// number of blocks that will fit into one dma buffer	unsigned long status = 0;	// nblk = 0 -> single	// nblk > 0 -> multiple	// nblk < 0 -> not supported for sdhc_read_ex/sdhc_write#if 0	db ("sdhc_read_ex: addr=0x%08lx, data=0x%08lx, blklen=%d, nblk=%ld, flags=0x%08lx\n\r",		 addr, (unsigned long)data, blklen, nblk, flags);#endif	if (RW_NOREAD_EN (flags)) {	       	if (!RW_DMA_EN(flags)) {			myprintf ("sdhc_read_ex: dma must be enabled for RW_NOREAD_EN\n\r");			return -1;		}	}	CEIL (nblk, 65535);	SSD_REGWW(REG_u16NrmIntrStatus , (RW_DMA_EN(flags) ? INTR_DMA : INTR_BUF_RD_RDY));		// enable the data status registers	SSD_REGWW(REG_u16NrmIntrStatusEn, SSD_REGRW(REG_u16NrmIntrStatusEn)& ~(INTR_BUF_RD_RDY | INTR_DMA));	SSD_REGWW(REG_u16NrmIntrStatusEn, SSD_REGRW(REG_u16NrmIntrStatusEn) | (INTR_DAT_COMPLETE | INTR_DMA | INTR_ERR));	SSD_REGWW(REG_u16ErrIntrStatusEn, SSD_REGRW(REG_u16ErrIntrStatusEn) | (EINTR_DAT_TOUT | EINTR_DAT_CRC | EINTR_DAT_END | EINTR_AUTOCMD12 |EINTR_VS_RSP_DIR | EINTR_VS_DAT_CONFLICT));#if 0	SSD_REGWW(REG_u16NrmIntrSignalEn |= (INTR_DAT_COMPLETE | INTR_DMA | INTR_ERR);	SSD_REGWW(REG_u16ErrIntrSignalEn |= (EINTR_DAT_TOUT | EINTR_DAT_CRC | EINTR_DAT_END | EINTR_AUTOCMD12 | 				EINTR_VS_RSP_DIR | EINTR_VS_DAT_CONFLICT);#endif	SSD_REGWW(REG_u16BlkSize , 0);	SSD_REGWW(REG_u16TrnsfrMode , TMR_RD_EN);	// make sure direction bit toggles	SSD_REGWW(REG_u16TrnsfrMode , 0);	SSD_REGWW(REG_u16TrnsfrMode, SSD_REGRW(REG_u16TrnsfrMode)| TMR_RD_EN | TMR_AUTOCMD12_EN |			(nblk != 0 ? TMR_MULTI_EN : 0) |	// nblk > 0 or nblk < 0 -> enable multiple			(nblk > 0 ? TMR_BLKCNT_EN : 0));	// setup for read transfer 	SSD_REGWW(REG_u16BlkCount , (unsigned short) SWAP32 (nblk));	SSD_REGWW(REG_u16BlkSize , SWAP16 (blklen));	event = INTR_ERR;	// calculate how many blocks can fit into the buffer without crossing the boundary	blks_per_buf = (DMA_BASE_END - data) / blklen;	//db ("sdhc_read_ex: blks_per_buf = %lu\n\r", blks_per_buf);	SSD_REGWW(REG_u16TrnsfrMode, SSD_REGRW(REG_u16TrnsfrMode) | TMR_DMA_EN);	SSD_REGWW(REG_u16BlkSize ,SSD_REGRW(REG_u16BlkSize)| SWAP16 (HST_BNDRY_512KB << 12));	SSD_REGWL(REG_u32DMAAddr , SWAP32 (data));	// start timer here			rsp[0] = addr;	if (send_cmd_SD (			nblk ? CMD_RD_MULTIPLE : CMD_RD_SINGLE, 			NORMAL, R48, 1, 1, 1, rsp) < 0)	{		myprintf ("sdhc_read_ex: Read Command(CMD%d) Failed\n\r",			nblk ? CMD_RD_MULTIPLE : CMD_RD_SINGLE);		error = 1;		goto l_err;	}	if (rsp[0] & (R1_STAT_ERR | R1_STAT_ADDR_ERR | R1_STAT_OORANGE))	{		myprintf ("sdhc_read_ex: Read Command(CMD%d) rejected by card\n\r",			nblk ? CMD_RD_MULTIPLE : CMD_RD_SINGLE);		decode_r1 (rsp[0]);		error = 1;		goto l_err;	}	blkcnt = 0;	event |= ((nblk <= blks_per_buf) ? INTR_DAT_COMPLETE : INTR_DMA);	// start receiving data	do {		int trial;		// for IO, INTR_DAT_COMPLETE is only set when the last block has been read out from the FIFO.		// for DMA, INTR_DAT_COMPLETE is set when the last block has been transferred from FIFO into 		// amazon memory even though the last address may not be on a DMA host boundary		db ("sdhc_read_ex: nblk=%ld, blks_read = %lu event=0x%04x\n\r",nblk, (unsigned long)blkcnt, SWAP16(event));							for(trial=0;trial<2000000;trial++)		{			if( (nisr = SSD_REGRW(REG_u16NrmIntrStatus)) & event)			{				break;			}			mdelay(10);		}				//while (!(nisr = SSD_REGWW(REG_u16NrmIntrStatus) & event)		//	;		// any errors		if (SSD_REGRW(REG_u16ErrIntrStatus)) {			db ("sdhc_read_ex: (Error!) NISR = 0x%x, EISR =0x%x\n\r", SWAP16 (SSD_REGRW(REG_u16NrmIntrStatus)), SWAP16(SSD_REGRW(REG_u16ErrIntrStatus)));							error = 1;			break;		}		SSD_REGWW(REG_u16NrmIntrStatus , ((event & INTR_DMA) ? INTR_DMA : INTR_DAT_COMPLETE));		if (event & INTR_DMA)		{			// set the next address here to continue the dma before any overrun			// occurs			SSD_REGWL(REG_u32DMAAddr , SWAP32(data));			blkcnt += blks_per_buf;			event = INTR_ERR | (((nblk - blkcnt) <= blks_per_buf) ? INTR_DAT_COMPLETE : INTR_DMA);		} else {			// we got a INTR_DAT_COMPLETE			tmp = nblk ? (nblk - blkcnt) : 1;			blkcnt += tmp;		}	} while (nblk && blkcnt < nblk);	// stop timer here	if (error) {		sdhc_reset (SW_RESET_DATA);		sdhc_reset (SW_RESET_CMD);	}	// though an autocmd12 could have been sent, we could have reached this point from error 	// reset or normal completion. In any case, get status should indicate that the card is 	// in transfer state	if (!nblk)		goto l_err;	// no need to send abort for single read	if (sdhc_get_status (&status) == 0) {		if (R1_STATE_NR(status) == R1_STATE_DATA) {			rsp[0] = 0xFFFFFFFF;			if (send_cmd_SD (CMD_STOP_TRANSMISSION, ABORT, R48b, 0, 1, 1, rsp) < 0) {				db ("sdhc_read_ex: get status failed\n\r");				g_card_err = 1;				error = 1;				goto l_err;			}			if ((sdhc_get_status (&status) < 0) ||				(R1_STATE_NR(status) != R1_STATE_TRAN)) {					g_card_err = 1;					error = 1;					goto l_err;			}		} else if (R1_STATE_NR (status) != R1_STATE_TRAN) {			db ("sdhc_read_ex: card is in unexpected state (%s)\n\r", R1_STATE(status));			g_card_err = 1;			error = 1;		}	} else {		db ("sdhc_read_ex: first get status failed\n\

⌨️ 快捷键说明

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