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

📄 pflash.c

📁 SigmDesign SMP8634 media decode chip development SDK
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		for (ii = 0; ii < (length-3); ii+=4, data+=4) {			*(RMuint32 *)data = gbus_read_remapped_uint32(h, pcfi->gbus_address + addroffs) ;			addroffs+=4; 		}		while ((length & 0x3) > 0) {			*(RMuint8 *)(data++) = gbus_read_remapped_uint8(h, pcfi->gbus_address + addroffs);			addroffs++;			length--;		}	}	return RM_OK;}/******************************************* RMstatus flash_write_data(struct gbus *h,  cfi_info *pcfi, RMuint32 addroffs, RMuint8 *data, RMuint32 length, void(*cb_usleep)(struct gbus*, RMuint32))** Description :* Write a region of specified parallel flash chip ** Input parameters:* pcfi: Pointer to parallel flash structure* addroffs: start offset address of parallel flash write region  (0 - pflash size)* *data: source address of write data* length: write length** Return values:* OK: operation successful; * fail: error message******************************************/#define UNLOCKBYPASSPROGRAM_UNITBITS	12	  // 2^12 = 4KBRMstatus flash_write_data(struct gbus *h,  cfi_info *pcfi, RMuint32 addroffs, RMuint8 *data, RMuint32 length, void(*cb_usleep)(struct gbus*, RMuint32)){	RMint32 len = length;	RMint32 maxbufwords, nwords;	RMuint32 addr = addroffs + pcfi->gbus_address;	RMstatus rc; 	RMint32 prtloop=0;	if (!pcfi->exist)		return RM_NOT_FOUND;	rc = flash_writable(h, addr, len);	if( rc != RM_OK)		return rc ;	if (addr & 0x01) {		rc = flash_write_onebyte(h, pcfi, addr++, *data++, cb_usleep);		if( rc != RM_OK)			return rc ;		--len;	}	if (pcfi->ident.max_multibyte_write == 0)		maxbufwords = 1 << (UNLOCKBYPASSPROGRAM_UNITBITS - 1);	else 		maxbufwords = 1 << (pcfi->ident.max_multibyte_write - 1);	//prints '.' after this block is written, 0x1000	RMDBGPRINT((LOCALDBG,"."));	while (len > 1) {		//RMDBGPRINT((LOCALDBG,"$"));		nwords = (len >> 1); //((len + 1) >> 1);		if (nwords > maxbufwords)			nwords = maxbufwords;		rc = flash_write_data_internal(h, addr, (RMuint16 *) data, nwords, pcfi, cb_usleep);		if( rc != RM_OK)			return rc ;		nwords <<= 1;		addr += nwords;		data += nwords;		len -= nwords;		prtloop += nwords;		if(prtloop >= 0x800) {			RMDBGPRINT((LOCALDBG,"."));			prtloop -= 0x800;		}	}	if (len == 1) {		rc = flash_write_onebyte(h, pcfi, addr, *data, cb_usleep);		if( rc != RM_OK)			return rc ;	}	return RM_OK;}RMstatus flash_save_write_data(struct gbus *h, cfi_info *pcfi, RMuint32 addroffs, RMuint32 ramaddr, RMuint32 length, void(*cb_usleep)(struct gbus*, RMuint32)){	RMuint32 start, blocksize;	RMuint32 wraddr,wrlen;	RMuint32 prtloop=0;	if (length == 0)		return RM_OK;	if (!pcfi->exist)		return RM_NOT_FOUND;	if( flash_writable(h, pcfi->gbus_address + addroffs, length) == RM_OK) {		if( flash_write_data(h, pcfi, addroffs, (RMuint8 *)ramaddr, length, cb_usleep) != RM_OK)			return RM_ERROR;		else 			return RM_OK;	}	// need erase first	if (flash_calcblock(h, pcfi, addroffs, &start, &blocksize) < 0)		return RM_NOT_FOUND;	do {		if (blocksize > MAXREGIONSIZE) {			RMDBGPRINT((LOCALDBG,"Please increase save buffer size!!\n"));			return !RM_OK;		}		flash_read_data(h, pcfi, start, savebuf, blocksize);		wraddr = addroffs - start;		wrlen = (length <= blocksize - wraddr ? length : blocksize - wraddr );		memcpy( &savebuf[wraddr], (RMuint8 *)ramaddr, wrlen);		if( flash_erase_oneblock(h, pcfi, start + pcfi->gbus_address, cb_usleep) != RM_OK)			return RM_ERROR;		if( flash_write_data(h, pcfi, start, savebuf, blocksize, cb_usleep) != RM_OK)			return RM_ERROR;		start += blocksize;		if (flash_calcblock(h, pcfi, start, &start, &blocksize) < 0)			break;		ramaddr += wrlen;		addroffs += wrlen;		length -= wrlen;		prtloop += blocksize;		if(prtloop >= 0x40000) {			RMDBGPRINT((LOCALDBG,"\n"));			prtloop -= 0x40000;		}	} while (start < addroffs + length);	return RM_OK;}/******************************************* RMint32 flash_calcblock(struct gbus *h, cfi_info *pcfi, RMuint32 addroffs, RMuint32 *pstart, RMuint32 *plen)** Description :* Calculate the block start address and length of parallel flash at given address offset* It can be used to calculate the block address and length that will be erased.** Input parameters:* pcfi: Pointer to parallel flash structure* addroffs: offset address of parallel flash * *pstart: point to block start address* *plen: point to block length** Return values:* OK: operation successful; * fail: error message******************************************/RMint32 flash_calcblock(struct gbus *h, cfi_info *pcfi, RMuint32 addroffs, RMuint32 *pstart, RMuint32 *plen){	RMint32 i;	if (!pcfi->exist)		return RM_NOT_FOUND;	*pstart = 0;	*plen = 0;	for (i = pcfi->ident.num_erase_regions - 1; i >= 0; --i) {		if (addroffs >= pcfi->erase_regions[i].start) {			*pstart = pcfi->erase_regions[i].start;			*plen = pcfi->erase_regions[i].size;			addroffs -= *pstart;			while (addroffs >= *plen) {				addroffs -= *plen;				*pstart += *plen;			}			return 0;		}	}	return -1;}/************************************************************************ *  Implementation : Static functions ************************************************************************/static void dqx_wait(struct gbus *h, RMuint32 addr, RMuint32 buswidth, RMuint32 datum, RMuint32 wait, void(*cb_usleep)(struct gbus *,RMuint32)){	RMuint32 dq6, dq5;	RMuint32 status, oldstatus, res;	unsigned int waitloop=0;	dq6 = cfi_build_cmd(1<<6,buswidth);	dq5 = cfi_build_cmd(1<<5,buswidth);	(*cb_usleep)(h,wait);	oldstatus = cfi_read(h,addr,buswidth);	status = cfi_read(h,addr,buswidth);	if((buswidth==CFIDEV_BUSWIDTH_16) && (datum==0xff)) {		oldstatus &= 0xff;		status &= 0xff;	}	if (flash_wait_div <= 1) 		res = wait;	else		res = wait/flash_wait_div;	while ((status != datum) || 		(((status & dq6) != (oldstatus & dq6)) && ((status & dq5) != dq5))) {		(*cb_usleep)(h,res);		oldstatus = cfi_read(h,addr,buswidth);		status = cfi_read(h,addr,buswidth);		if(waitloop==5) {			RMDBGPRINT((LOCALDBG,"pflash write/erase timeout fails.\n"));			break;		} else {			RMDBGPRINT((LOCALDBG,"*"));			waitloop++;		}	}}//// CFI basic I/O//static RMuint32 cfi_read(struct gbus  *h,  RMuint32 addr, RMuint32 bwidth){	RMuint32 data;	switch (bwidth) {	case CFIDEV_BUSWIDTH_8 : 		data = gbus_read_remapped_uint8(h, addr);		break;	case CFIDEV_BUSWIDTH_16 : 		data = gbus_read_remapped_uint16(h, addr);		break;	case CFIDEV_BUSWIDTH_32 :		data = gbus_read_remapped_uint32(h, addr);		break;	default :		return 0;	}	RMDBGLOG((DISABLE,"FLASH Read addr = 0x%x, data = 0x%x\n", addr, data));	return data;}static void cfi_write(struct gbus  *h, RMuint32 bwidth, RMuint32 val, RMuint32 addr){	RMDBGLOG((DISABLE,"FLASH Write addr = %08lx, data = 0x%x\n", addr, val));	switch (bwidth) { 	case CFIDEV_BUSWIDTH_8 : 		gbus_write_remapped_uint8(h, addr, val);		break;	case CFIDEV_BUSWIDTH_16 : 		gbus_write_remapped_uint16(h, addr, val);		break;	case CFIDEV_BUSWIDTH_32 :		gbus_write_remapped_uint32(h, addr, val);		break;	default :		return;	}}// // CFI advanced I/O//// bus width address => byte addressstatic RMuint32 cfi_build_cmd_addr(RMuint32 addr){	return addr * CFIDEV_DEVTYPE * CFIDEV_INTERLEAVE;}static RMuint32 cfi_build_cmd(RMuint32 cmd, RMuint32 bwidth){	RMuint32 val = 0;	switch (bwidth) {	case CFIDEV_BUSWIDTH_8 : 		val = cmd;		break;	case CFIDEV_BUSWIDTH_16 : 		if (CFIDEV_INTERLEAVE == 1)			val = cpu_to_cfi16(cmd);		else if (CFIDEV_INTERLEAVE == 2)			val = cpu_to_cfi16((cmd << 8) | cmd);		break;	case CFIDEV_BUSWIDTH_32 : 		if (CFIDEV_INTERLEAVE == 1)			val = cpu_to_cfi32(cmd);		else if (CFIDEV_INTERLEAVE == 2)			val = cpu_to_cfi32((cmd << 16) | cmd);		else if (CFIDEV_INTERLEAVE == 4) {			val = (cmd << 16) | cmd;			val = cpu_to_cfi32((val << 8) | val);		}		break;	default :		break;	}	return val;}static void cfi_send_cmd(struct gbus  *h, RMuint32 bwidth, RMuint32 cmd, RMuint32 cmd_addr, RMuint32 base){	cfi_write(h, bwidth, cfi_build_cmd(cmd,bwidth), base + cmd_addr);}//// probing & setup// static RMstatus cfi_probe_chip(struct gbus  *h, cfi_info *pcfi){	RMint32 ret;	RMuint32 addr_probe1, addr_probe2;	RMuint32 data_probe1, data_probe2;	addr_probe1 = pcfi->gbus_address + cfi_build_cmd_addr(0);	addr_probe2 = pcfi->gbus_address + cfi_build_cmd_addr(0x55);	data_probe1 = cfi_read(h,  addr_probe1, pcfi->buswidth);	data_probe2 = cfi_read(h,  addr_probe2, pcfi->buswidth);	// Reset	cfi_send_cmd(h, pcfi->buswidth, 0xf0, 0, pcfi->gbus_address);	// Enter CFI Query mode	cfi_send_cmd(h, pcfi->buswidth, 0x98, cfi_build_cmd_addr(0x55), pcfi->gbus_address);	if ((ret = cfi_query_present(h, pcfi->gbus_address, pcfi->buswidth)) != RM_OK) {		cfi_write(h, pcfi->buswidth, data_probe1, addr_probe1);		cfi_write(h, pcfi->buswidth, data_probe2, addr_probe2);		return ret;	}

⌨️ 快捷键说明

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