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

📄 smi.c.svn-base

📁 Spearhead2000 的 USB驱动程序
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************                                                                           ****  Copyright (c) 2005 ST Microelectronics                                   ****  All rights reserved                                                      ****                                                                           ****     Filename  :  smi.c                                                    ****     Authors in alphabetical order :  Gianfranco Di Nuzzo - Stefano Romano ****     Revision  :  3.2                                                      ****                                                                           ****                                                                           ****                                                                           *********************************************************************************//******************************************************************************/#include "vic_pl190.h"#include "smi.h"#include "uart.h"#include "gpio.h"#include <apb_configuration.h>unsigned int opComplete = 1;/************************ interrupt handler ************************/void smi_int_handler(){    	volatile unsigned int val;    	val = SMICntl->SMI_SR;	if (val & CHECK_WCF)     	{	SMICntl->SMI_SR &= ~(WCF); /* WriteCompleteFlag interrupt clear */		opComplete = 1;	}	else	{		if (val & CHECK_TFF)    		SMICntl->SMI_SR &= ~(TFF); /* TranserFinishFlag interrupt clear */		opComplete = 1;	}}/************************** init *************************/void smi_init(){	/* interrupt enabling */	intctlIntRegister(ITC_SMI_int, smi_int_handler, 1);        /* Setting the standard values */	SMICntl->SMI_CR1 = BANK_EN | DSEL_TIME | PRESCALA;}/***********************************************************************//************************* Utilities - routines ************************//***********************************************************************//****************************** Vendor And ID Read *****************************/unsigned int smi_read_id(unsigned int bank){/**** NOTE: READ ID IS PERFORMED IN SW MODE ****/	unsigned int B_SEL;	unsigned int value;	unsigned int SAVE_CR1;	unsigned int SAVE_CR2;		switch(bank)	{		case BANK0: B_SEL = BANK0_SEL; break;		case BANK1: B_SEL = BANK1_SEL; break;		case BANK2: B_SEL = BANK2_SEL; break;		case BANK3: B_SEL = BANK3_SEL; break;	}	/*** Saving CR1-2 ***/	/**************** put SMI in SW mode **************/	SMICntl->SMI_CR1 |= SW_MODE;		/*** Clear TFF ***/	SMICntl->SMI_SR &= ~TFF;	/*** Check if Flash is WIP in HW mode***/	SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;	while (!(SMICntl->SMI_SR & TFF));	while (SMICntl->SMI_SR & WIP_BIT) 		{			SMICntl->SMI_SR &= ~TFF;			SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;			while (!(SMICntl->SMI_SR & TFF));		}	/*** Clear TFF ***/	SMICntl->SMI_SR &= ~TFF;	/*** Send ReadID command in SW Mode ***/	SMICntl->SMI_TR  = READ_ID;	SMICntl->SMI_CR2 = B_SEL | SEND | TX_LEN_1 | RX_LEN_3;;	/*** Check if Flash Read_id is Finished ***/	while (!(SMICntl->SMI_SR & TFF));	/*** Clear SR TFF ***/	SMICntl->SMI_SR &= ~TFF;	value = (SMICntl->SMI_RR & 0x00FFFFFF);	/*** Reloading CR1-2 ***/	/*** Returning FLASH ID value ***/		/*** Put SMI in HW mode ***/	SMICntl->SMI_CR1 &= ~(SW_MODE);		return(value);}/****************************** Read Status Register *****************************/unsigned int smi_read_sr(unsigned int bank){	unsigned int B_SEL;	unsigned int value;	unsigned int SAVE_CR1;	unsigned int SAVE_CR2;		switch(bank)	{		case BANK0: B_SEL = BANK0_SEL; break;		case BANK1: B_SEL = BANK1_SEL; break;		case BANK2: B_SEL = BANK2_SEL; break;		case BANK3: B_SEL = BANK3_SEL; break;	}	/*** Put SMI in HW mode ***/	SMICntl->SMI_CR1 &= ~(SW_MODE);	/*** Clear TFF ***/	SMICntl->SMI_SR &= ~TFF;	/*** Performing a RSR instruction in HW mode ***/	SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;	while (!(SMICntl->SMI_SR & TFF));	/*** Returning STATUS Register value ***/	value=SMICntl->SMI_SR;	/*** Clear SR TFF ***/	SMICntl->SMI_SR &= ~TFF;	/*** Reloading CR1-2 ***/	return(value);}/********************************** Read *******************************/void smi_read(unsigned int* src_addr, unsigned int* dst_addr, unsigned int length, unsigned int bank){	unsigned int i;	unsigned int SAVE_CR1;	unsigned int SAVE_CR2;	/*** Saving CR1-2 ***/	/* src_addr is a pointer so it is multiplied by 4 */	switch(bank)	{		case BANK0: src_addr += SMIBANK0_BASE / 4; break; 		case BANK1: src_addr += SMIBANK1_BASE / 4; break;		case BANK2: src_addr += SMIBANK2_BASE / 4; break;		case BANK3: src_addr += SMIBANK3_BASE / 4; break;	}	/*** Put SMI in HW mode not WBT mode ***/	SMICntl->SMI_CR1 &= ~(SW_MODE | WB_MODE);	/*** Clear SR TFF ***/	SMICntl->SMI_SR &= ~TFF;	/*** Perform the read command ***/	for(i=0; i<length; i++) 	{		dst_addr[i] = src_addr[i];	}	/*** Clear SR TFF ***/	/*** Reloading CR1-2 ***/}/********************************** Write *******************************/int smi_write(unsigned int* src_addr, unsigned int* dst_addr, unsigned int length, unsigned int bank){	unsigned int i;	unsigned int j=0;	unsigned int B_SEL;	unsigned int SAVE_CR1;	unsigned int SAVE_CR2;	unsigned int WM;	/* src_addr is a pointer so it is multiplied by 4 */	switch(bank)	{		case BANK0: dst_addr += SMIBANK0_BASE / 4; B_SEL = BANK0_SEL; WM = WM0; break;		case BANK1: dst_addr += SMIBANK1_BASE / 4; B_SEL = BANK1_SEL; WM = WM1; break;		case BANK2: dst_addr += SMIBANK2_BASE / 4; B_SEL = BANK2_SEL; WM = WM2; break;		case BANK3: dst_addr += SMIBANK3_BASE / 4; B_SEL = BANK3_SEL; WM = WM3; break;	}	/*** Put SMI in HW mode not WBT mode ***/	SMICntl->SMI_CR1 &= ~(SW_MODE | WB_MODE);		/* Clear the write mode */	SMICntl->SMI_SR &= ~(WM);	/*** Clear SR TFF ***/	SMICntl->SMI_SR &= ~TFF;	/*** Check if Flash is WIP in HW mode***/	SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;	while (!(SMICntl->SMI_SR & TFF));	while (SMICntl->SMI_SR & WIP_BIT) 		{			SMICntl->SMI_SR &= ~TFF;			SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;			while (!(SMICntl->SMI_SR & TFF));		}	/*** Clear TFF ***/	SMICntl->SMI_SR &= ~TFF;	SMICntl->SMI_CR1 |= (WB_MODE);	/*********** Put the Flash in WE and check ************/	SMICntl->SMI_CR2 = WE | B_SEL;	while (!(SMICntl->SMI_SR & WM));		/*** Perform the write command ***/	for(i=0; i<length; i++)	{		if ((((unsigned int)(dst_addr)+(i))%0x100) == 0)                 {			/*** Clear SR TFF ***/			SMICntl->SMI_SR &= ~TFF;			/*** Check if Flash is WIP in HW mode***/			SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;			while (!(SMICntl->SMI_SR & TFF));			while (SMICntl->SMI_SR & WIP_BIT) 			{				SMICntl->SMI_SR &= ~TFF;				SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;				while (!(SMICntl->SMI_SR & TFF));			}			/*** Clear TFF ***/			SMICntl->SMI_SR &= ~TFF;			/*********** Put the Flash in WE and check ************/			SMICntl->SMI_CR2 = WE | B_SEL;			while (!(SMICntl->SMI_SR & WM));	  		}		dst_addr[i] = src_addr[i];		if(i==(length-1))	        {	            /* Reset the burst mode  */	            SMICntl->SMI_CR1 &= ~(WB_MODE);	        }		if ((SMICntl->SMI_SR & (ERF1 | ERF2))) 		{			/*** Clear SR TFF ***/			/*** Reloading CR1-2 ***/			return(-1);		}	}	/*** Clear SR TFF ***/	/*** Reloading CR1-2 ***/	return(0);}/****************************** BANK Erase *****************************/int smi_bank_erase(unsigned int bank){/**** NOTE: BANK ERASE IS PERFORMED IN SW MODE ****/	unsigned int B_SEL;	unsigned int SAVE_CR1;	unsigned int SAVE_CR2;	unsigned int WM;		switch(bank)	{		case BANK0: B_SEL = BANK0_SEL; WM = WM0; break;		case BANK1: B_SEL = BANK1_SEL; WM = WM1; break;		case BANK2: B_SEL = BANK2_SEL; WM = WM2; break;		case BANK3: B_SEL = BANK3_SEL; WM = WM3; break;	}	/*** Saving CR1-2 ***/	/*** Clearing Error Flags ***/	if (smi_read_id(bank) == ST_M25P64) 	{		/*** Programming CR1 in a Known State ***/		SMICntl->SMI_CR1 |= SW_MODE;				/*** Clear TFF ***/		SMICntl->SMI_SR &= ~TFF;		/*** Check if Flash is WIP in HW mode***/		SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;		while (!(SMICntl->SMI_SR & TFF));		while (SMICntl->SMI_SR & WIP_BIT) 		{			SMICntl->SMI_SR &= ~TFF;			SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;			while (!(SMICntl->SMI_SR & TFF));		}                        /*** Clear TFF ***/ 	        		SMICntl->SMI_SR &= ~TFF;		/*********** Put the Flash in WE and check ************/		SMICntl->SMI_CR2 = WE | B_SEL;        while (!(SMICntl->SMI_SR & TFF));        /*** Clear TFF ***/ 							 		         SMICntl->SMI_SR &= ~TFF;						 		         /*** Check if Flash is WEL in HW mode***/		 		         SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;		 		         while (!(SMICntl->SMI_SR & TFF));				 		         while (!(SMICntl->SMI_SR & WEL_BIT))				 		         {												 		                 SMICntl->SMI_SR &= ~TFF;				 		                 SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;		                 while (!(SMICntl->SMI_SR & TFF));		 		         }												 		 		/*** Clear TFF ***/		SMICntl->SMI_SR &= ~TFF;        /*** Send BulkErase command in SW Mode ***/		SMICntl->SMI_TR  = BULK_ERASE;		SMICntl->SMI_CR2 = B_SEL |SEND | TX_LEN_1;		while (!(SMICntl->SMI_SR & TFF));	         /*** Clear TFF ***/ 							 		         SMICntl->SMI_SR &= ~TFF;						 		 				/*** Check if Flash is WIP in HW mode***/		SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;		while (!(SMICntl->SMI_SR & TFF));		while (SMICntl->SMI_SR & WIP_BIT) 		{			SMICntl->SMI_SR &= ~TFF;			SMICntl->SMI_CR2 = B_SEL | RD_STATUS_REG;			while (!(SMICntl->SMI_SR & TFF));		}		/*** Clear TFF ***/		SMICntl->SMI_SR &= ~TFF;		/*** Checking for Errors ***/		if ((SMICntl->SMI_SR & (ERF1 | ERF2))) 		{			/*** Put SMI in HW mode ***/			SMICntl->SMI_CR1 &= ~(SW_MODE);				/*** Reloading CR1-2 ***/			return(-1);		}

⌨️ 快捷键说明

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