📄 smi.c.svn-base
字号:
/******************************************************************************** **** 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 + -