1 /******************** (C) COPYRIGHT 2006 STMicroelectronics ********************
\r
2 * File Name : 91x_fmi.c
\r
3 * Author : MCD Application Team
\r
4 * Date First Issued : 05/18/2006 : Version 1.0
\r
5 * Description : This file provides all the FMI software functions.
\r
6 ********************************************************************************
\r
8 * 05/24/2006 : Version 1.1
\r
9 * 05/18/2006 : Version 1.0
\r
10 ********************************************************************************
\r
11 * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
\r
12 * CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS
\r
13 * A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
\r
14 * OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
\r
15 * OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
\r
16 * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
\r
17 *******************************************************************************/
\r
20 /* Standard include ----------------------------------------------------------*/
\r
21 #include "91x_fmi.h"
\r
23 /* Include of other module interface headers ---------------------------------*/
\r
24 /* Local includes ------------------------------------------------------------*/
\r
25 /* Private typedef -----------------------------------------------------------*/
\r
26 /* Private define ------------------------------------------------------------*/
\r
28 #define TIMEOUT 0xFFFFFF /* Timeout value */
\r
30 /* Private macro -------------------------------------------------------------*/
\r
31 /* Private variables ---------------------------------------------------------*/
\r
32 /* Private function prototypes -----------------------------------------------*/
\r
33 /* Interface functions -------------------------------------------------------*/
\r
34 /* Private functions ---------------------------------------------------------*/
\r
37 /*******************************************************************************
\r
38 * Function Name : FMI_BankRemapConfig
\r
39 * Description : Configure the addresses and sizes of bank 0 and bank 1.
\r
40 * Input1 : FMI_BootBankSize: specifies the boot bank size.
\r
41 * This parameter can be one of the following values:
\r
49 * Input2 : FMI_NonBootBankSize: specifies the non boot bank size.
\r
50 * This parameter can be one of the following values:
\r
57 * Input3 : FMI_BootBankAddress: specifies the address of the boot bank.
\r
58 * Input4 : FMI_NonBootBankAddress: specifies the address of the non
\r
62 *******************************************************************************/
\r
63 void FMI_BankRemapConfig(u8 FMI_BootBankSize, u8 FMI_NonBootBankSize, \
\r
64 u32 FMI_BootBankAddress, u32 FMI_NonBootBankAddress)
\r
66 FMI->BBSR = FMI_BootBankSize;
\r
67 FMI->NBBSR = FMI_NonBootBankSize;
\r
68 FMI->BBADR = (FMI_BootBankAddress >> 2);
\r
69 FMI->NBBADR = (FMI_NonBootBankAddress >> 2);
\r
70 FMI->CR |= 0x18; /* Enable bank 1 */
\r
73 /*******************************************************************************
\r
74 * Function Name : FMI_Config
\r
75 * Description : Configure the FMI.
\r
76 * Input1 : FMI_ReadWaitState: specifies the needed read wait states.
\r
77 * This parameter can be one of the following values:
\r
78 * - FMI_READ_WAIT_STATE_1: One read wait state.
\r
79 * - FMI_READ_WAIT_STATE_2: Two read wait states.
\r
80 * - FMI_READ_WAIT_STATE_3: Three read wait states.
\r
81 * Input2 : FMI_WriteWaitState: specifies the needed write wait states.
\r
82 * This parameter can be one of the following values:
\r
83 * - FMI_WRITE_WAIT_STATE_1: One write wait state.
\r
84 * - FMI_WRITE_WAIT_STATE_2: Two write wait states.
\r
85 * Input3 : FMI_PWD: specifies the power down mode status.
\r
86 * This parameter can be one of the following values:
\r
87 * - FMI_PWD_ENABLE: Enable the PWD.
\r
88 * - FMI_PWD_DISABLE: Disable the PWD.
\r
89 * Input4 : FMI_LVDEN: specifies the low voltage detector status.
\r
90 * This parameter can be one of the following values:
\r
91 * - FMI_LVD_ENABLE: Enable the LVD.
\r
92 * - FMI_LVD_DISABLE: Disable the LVD.
\r
93 * Input5 : FMI_FreqRange: specifies the working frequency range.
\r
94 * This parameter can be one of the following values:
\r
95 * - FMI_FREQ_LOW: Low working frequency (up to 66MHz).
\r
96 * - FMI_FREQ_HIGH: High working frequency (above 66MHz) .
\r
99 *******************************************************************************/
\r
100 void FMI_Config(u16 FMI_ReadWaitState, u32 FMI_WriteWaitState, u16 FMI_PWD,\
\r
101 u16 FMI_LVDEN, u16 FMI_FreqRange)
\r
103 /* Configure the write wait state value */
\r
104 if (FMI_WriteWaitState == FMI_WRITE_WAIT_STATE_1)
\r
106 FMI->CR |= FMI_WRITE_WAIT_STATE_1;
\r
110 FMI->CR &= FMI_WRITE_WAIT_STATE_0;
\r
113 /* Write a write flash configuration register command */
\r
114 *(vu16 *)FMI_BANK_1 = 0x60;
\r
116 /* Configure the flash configuration register */
\r
117 *(vu16 *)(FMI_BANK_1|FMI_ReadWaitState|FMI_PWD|FMI_LVDEN|FMI_FreqRange) = 0x03;
\r
120 /*******************************************************************************
\r
121 * Function Name : FMI_EraseSector
\r
122 * Description : Erase the needed sector.
\r
123 * Input : FMI_Sector: specifies the sector to be erased.
\r
124 * This parameter can be one of the following values:
\r
125 * - FMI_B0S0: FMI bank 0 sector 0.
\r
126 * - FMI_B0S1: FMI bank 0 sector 1.
\r
127 * - FMI_B0S2: FMI bank 0 sector 2.
\r
128 * - FMI_B0S3: FMI bank 0 sector 3.
\r
129 * - FMI_B0S4: FMI bank 0 sector 4.
\r
130 * - FMI_B0S5: FMI bank 0 sector 5.
\r
131 * - FMI_B0S6: FMI bank 0 sector 6.
\r
132 * - FMI_B0S7: FMI bank 0 sector 7.
\r
133 * - FMI_B1S0: FMI bank 1 sector 0.
\r
134 * - FMI_B1S1: FMI bank 1 sector 1.
\r
135 * - FMI_B1S2: FMI bank 1 sector 2.
\r
136 * - FMI_B1S3: FMI bank 1 sector 3.
\r
139 *******************************************************************************/
\r
140 void FMI_EraseSector(vu32 FMI_Sector)
\r
142 /* Write an erase set-up command to the sector */
\r
143 *(vu16 *)FMI_Sector = 0x20;
\r
145 /* Write an erase confirm command to the sector */
\r
146 *(vu16 *)FMI_Sector = 0xD0;
\r
149 /*******************************************************************************
\r
150 * Function Name : FMI_EraseBank
\r
151 * Description : Erase the needed bank.
\r
152 * Input : FMI_Bank: specifies the bank to be erased.
\r
153 * This parameter can be one of the following values:
\r
154 * - FMI_BANK_0: FMI bank 0.
\r
155 * - FMI_BANK_1: FMI bank 1.
\r
158 *******************************************************************************/
\r
159 void FMI_EraseBank(vu32 FMI_Bank)
\r
161 /* Write a bank erase set-up command to the bank */
\r
162 *(vu16 *)FMI_Bank = 0x80;
\r
164 /* Write an erase confirm command to the sector */
\r
165 *(vu16 *)FMI_Bank = 0xD0;
\r
168 /*******************************************************************************
\r
169 * Function Name : FMI_WriteHalfWord
\r
170 * Description : Write a halfword to the needed Flash memory address.
\r
171 * Input 1 : FMI_Address: specifies the address offset where the data will
\r
173 * Input 2 : FMI_Data: the needed data.
\r
176 *******************************************************************************/
\r
177 void FMI_WriteHalfWord(u32 FMI_Address, u16 FMI_Data)
\r
179 /* Write a program command to the sector to be written */
\r
180 *(vu16 *)(FMI_Address & 0xFFFFFFFC) = 0x40;
\r
182 /* Write the halfword to the destination address */
\r
183 *(vu16 *)FMI_Address = FMI_Data;
\r
186 /*******************************************************************************
\r
187 * Function Name : FMI_WriteOTPHalfWord
\r
188 * Description : Write a halfword to the needed OTP sector address.
\r
189 * Input 1 : FMI_OTPHWAddress: specifies the halfword address offset
\r
190 * where the data will be written.
\r
191 * This parameter can be one of the following values:
\r
192 * - FMI_OTP_LOW_HALFWORD_0: OTP Low halfword 0.
\r
193 * - FMI_OTP_HIGH_HALFWORD_0: OTP High halfword 0.
\r
194 * - FMI_OTP_LOW_HALFWORD_1: OTP Low halfword 1.
\r
195 * - FMI_OTP_HIGH_HALFWORD_1: OTP High halfword 1.
\r
196 * - FMI_OTP_LOW_HALFWORD_2: OTP Low halfword 2.
\r
197 * - FMI_OTP_HIGH_HALFWORD_2: OTP High halfword 2.
\r
198 * - FMI_OTP_LOW_HALFWORD_3: OTP Low halfword 3.
\r
199 * - FMI_OTP_HIGH_HALFWORD_3: OTP High halfword 3.
\r
200 * - FMI_OTP_LOW_HALFWORD_4: OTP Low halfword 4.
\r
201 * - FMI_OTP_HIGH_HALFWORD_4: OTP High halfword 4.
\r
202 * - FMI_OTP_LOW_HALFWORD_5: OTP Low halfword 5.
\r
203 * - FMI_OTP_HIGH_HALFWORD_5: OTP High halfword 5.
\r
204 * - FMI_OTP_LOW_HALFWORD_6: OTP Low halfword 6.
\r
205 * - FMI_OTP_HIGH_HALFWORD_6: OTP High halfword 6.
\r
206 * - FMI_OTP_LOW_HALFWORD_7: OTP Low halfword 7.
\r
207 * - FMI_OTP_HIGH_HALFWORD_7: OTP High halfword 7.
\r
208 * Input 2 : FMI_OTPData: The needed OTP data.
\r
211 *******************************************************************************/
\r
212 void FMI_WriteOTPHalfWord(u8 FMI_OTPHWAddress, u16 FMI_OTPData)
\r
214 /* Write a write OTP command to the needed address */
\r
215 *(vu16 *)(FMI_BANK_1) = 0xC0;
\r
217 /* Write the halfword to the destination address */
\r
218 *(vu16 *)(FMI_BANK_1 + FMI_OTPHWAddress) = FMI_OTPData;
\r
221 /*******************************************************************************
\r
222 * Function Name : FMI_ReadWord
\r
223 * Description : Read the correspondent data.
\r
224 * Input : FMI_Address: specifies the needed address.
\r
226 * Return : The data contained in the specified address.
\r
227 *******************************************************************************/
\r
228 u32 FMI_ReadWord(u32 FMI_Address)
\r
230 return(*(u32*)FMI_Address);
\r
233 /*******************************************************************************
\r
234 * Function Name : FMI_ReadOTPData
\r
235 * Description : Read data from the OTP sector.
\r
236 * Input : FMI_OTPAddress: specifies the address of the data to be read.
\r
237 * This parameter can be one of the following values:
\r
238 * - FMI_OTP_WORD_0: FMI bank 0 sector 0.
\r
239 * - FMI_OTP_WORD_1: FMI bank 0 sector 1.
\r
240 * - FMI_OTP_WORD_2: FMI bank 0 sector 2.
\r
241 * - FMI_OTP_WORD_3: FMI bank 0 sector 3.
\r
242 * - FMI_OTP_WORD_4: FMI bank 0 sector 4.
\r
243 * - FMI_OTP_WORD_5: FMI bank 0 sector 5.
\r
244 * - FMI_OTP_WORD_6: FMI bank 0 sector 6.
\r
245 * - FMI_OTP_WORD_7: FMI bank 0 sector 7.
\r
247 * Return : The needed OTP words.
\r
248 *******************************************************************************/
\r
249 u32 FMI_ReadOTPData(u8 FMI_OTPAddress)
\r
251 u32 OTP_Data = 0x0;
\r
252 /* write a read OTP sector command */
\r
253 *(vu16 *)(FMI_BANK_1) = 0x98;
\r
255 /* Read the correspondent data */
\r
256 OTP_Data = (*(vu32*)(FMI_BANK_1 + FMI_OTPAddress));
\r
258 /* Write a read array command */
\r
259 *(vu16 *)(FMI_BANK_1) = 0xFF;
\r
264 /*******************************************************************************
\r
265 * Function Name : FMI_GetFlagStatus
\r
266 * Description : Check whether the specified FMI flag is set or not.
\r
267 * Input1 : FMI_Flag: flag to check.
\r
268 * This parameter can be one of the following values:
\r
269 * - FMI_FLAG_SPS: Sector Protection Status Flag.
\r
270 * - FMI_FLAG_PSS: Program Suspend Status Flag.
\r
271 * - FMI_FLAG_PS: Program Status Flag.
\r
272 * - FMI_FLAG_ES: Erase Status Flag.
\r
273 * - FMI_FLAG_ESS: Erase Suspend Status Flag.
\r
274 * - FMI_FLAG_PECS: FPEC Status Flag.
\r
275 * Input2 : FMI_Bank: specifies the needed bank.
\r
276 * This parameter can be one of the following values:
\r
277 * - FMI_BANK_0: FMI bank 0.
\r
278 * - FMI_BANK_1: FMI bank 1.
\r
281 *******************************************************************************/
\r
282 FlagStatus FMI_GetFlagStatus(u8 FMI_Flag, vu32 FMI_Bank)
\r
284 u16 FMI_Status_Register = 0;
\r
286 /* Write a read status register command */
\r
287 *(vu16 *)FMI_Bank = 0x70;
\r
289 /* Wait until operation completion */
\r
290 while(!((*(vu16 *)FMI_Bank) & 0x80));
\r
292 /* Read the status register */
\r
293 FMI_Status_Register = *(vu16 *)FMI_Bank;
\r
295 /* Write a read array command */
\r
296 *(vu16 *)FMI_Bank = 0xFF;
\r
298 if((FMI_Status_Register & FMI_Flag) != RESET)
\r
308 /*******************************************************************************
\r
309 * Function Name : FMI_GetReadWaitStateValue
\r
310 * Description : Get the current Read wait state value.
\r
313 * Return : The current read wait states value.
\r
314 *******************************************************************************/
\r
315 u16 FMI_GetReadWaitStateValue(void)
\r
317 u16 FMI_Configuration_Register = 0;
\r
318 /* Write a read flash configuration register command */
\r
319 *(vu16 *)FMI_BANK_1 = 0x90;
\r
321 /* Read the flash configuration register */
\r
322 FMI_Configuration_Register = *(vu16 *)(FMI_BANK_1 + 0x14);
\r
324 /* Write a read array command */
\r
325 *(vu16 *)FMI_BANK_1 = 0xFF;
\r
327 FMI_Configuration_Register = ((FMI_Configuration_Register>>11) + 1) & 0x3;
\r
329 /* Return the wait states value */
\r
330 return FMI_Configuration_Register;
\r
333 /*******************************************************************************
\r
334 * Function Name : FMI_GetWriteWaitStateValue
\r
335 * Description : Get the current write wait state value.
\r
338 * Return : The current write wait states value.
\r
339 *******************************************************************************/
\r
340 u16 FMI_GetWriteWaitStateValue(void)
\r
342 return ((u16)((FMI->CR & 0x100) >> 8));
\r
345 /*******************************************************************************
\r
346 * Function Name : FMI_SuspendEnable
\r
347 * Description : Suspend command enable.
\r
348 * Input : FMI_Bank: specifies the bank to be suspended.
\r
349 * This parameter can be one of the following values:
\r
350 * - FMI_BANK_0: FMI bank 0.
\r
351 * - FMI_BANK_1: FMI bank 1.
\r
354 *******************************************************************************/
\r
355 void FMI_SuspendEnable(vu32 FMI_Bank)
\r
357 /* Write a suspend command to the bank */
\r
358 *(vu16 *)FMI_Bank = 0xB0;
\r
361 /*******************************************************************************
\r
362 * Function Name : FMI_ResumeEnable
\r
363 * Description : Resume the suspended command.
\r
364 * Input : FMI_Bank: specifies the suspended bank.
\r
365 * This parameter can be one of the following values:
\r
366 * - FMI_BANK_0: FMI bank 0.
\r
367 * - FMI_BANK_1: FMI bank 1.
\r
370 *******************************************************************************/
\r
371 void FMI_ResumeEnable(vu32 FMI_Bank)
\r
373 /* Write a resume command to the bank */
\r
374 *(vu16 *)FMI_Bank = 0xD0;
\r
377 /*******************************************************************************
\r
378 * Function Name : FMI_ClearFlag
\r
379 * Description : Clear the FMI Flags on the correspondent bank.
\r
380 * Input : FMI_Bank: specifies the needed bank.
\r
381 * This parameter can be one of the following values:
\r
382 * - FMI_BANK_0: FMI bank 0.
\r
383 * - FMI_BANK_1: FMI bank 1.
\r
386 *******************************************************************************/
\r
387 void FMI_ClearFlag(vu32 FMI_Bank)
\r
389 /* Write a clear status register command */
\r
390 *(vu16 *)FMI_Bank = 0x50;
\r
393 /*******************************************************************************
\r
394 * Function Name : FMI_WriteProtectionCmd
\r
395 * Description : Enable or disable the write protection for the needed sector.
\r
396 * Input1 : FMI_Sector: specifies the sector to be protected or
\r
398 * This parameter can be one of the following values:
\r
399 * - FMI_B0S0: FMI bank 0 sector 0.
\r
400 * - FMI_B0S1: FMI bank 0 sector 1.
\r
401 * - FMI_B0S2: FMI bank 0 sector 2.
\r
402 * - FMI_B0S3: FMI bank 0 sector 3.
\r
403 * - FMI_B0S4: FMI bank 0 sector 4.
\r
404 * - FMI_B0S5: FMI bank 0 sector 5.
\r
405 * - FMI_B0S6: FMI bank 0 sector 6.
\r
406 * - FMI_B0S7: FMI bank 0 sector 7.
\r
407 * - FMI_B1S0: FMI bank 1 sector 0.
\r
408 * - FMI_B1S1: FMI bank 1 sector 1.
\r
409 * - FMI_B1S2: FMI bank 1 sector 2.
\r
410 * - FMI_B1S3: FMI bank 1 sector 3.
\r
411 * Input2 : FMI_NewState: specifies the protection status.
\r
412 * This parameter can be one of the following values:
\r
413 * - ENABLE: Enable the protection.
\r
414 * - DISABLE: Disable the protection.
\r
417 *******************************************************************************/
\r
418 void FMI_WriteProtectionCmd(vu32 FMI_Sector, FunctionalState FMI_NewState)
\r
420 if (FMI_NewState == ENABLE)
\r
422 *(vu16*)FMI_Sector = 0x60;
\r
423 *(vu16*)FMI_Sector = 0x01;
\r
424 *(vu16*)FMI_Sector = 0xFF;
\r
428 *(vu16*)FMI_Sector = 0x60;
\r
429 *(vu16*)FMI_Sector = 0xD0;
\r
430 *(vu16*)FMI_Sector = 0xFF;
\r
434 /*******************************************************************************
\r
435 * Function Name : FMI_GetWriteProtectionStatus
\r
436 * Description : Get the write protection status for the needed sector.
\r
437 * Input : FMI_Sector_Mask: specifies the needed sector mask.
\r
438 * This parameter can be one of the following values:
\r
439 * - FMI_B0S0_MASK: FMI bank 0 sector 0.
\r
440 * - FMI_B0S1_MASK: FMI bank 0 sector 1.
\r
441 * - FMI_B0S2_MASK: FMI bank 0 sector 2.
\r
442 * - FMI_B0S3_MASK: FMI bank 0 sector 3.
\r
443 * - FMI_B0S4_MASK: FMI bank 0 sector 4.
\r
444 * - FMI_B0S5_MASK: FMI bank 0 sector 5.
\r
445 * - FMI_B0S6_MASK: FMI bank 0 sector 6.
\r
446 * - FMI_B0S7_MASK: FMI bank 0 sector 7.
\r
447 * - FMI_B1S0_MASK: FMI bank 1 sector 0.
\r
448 * - FMI_B1S1_MASK: FMI bank 1 sector 1.
\r
449 * - FMI_B1S2_MASK: FMI bank 1 sector 2.
\r
450 * - FMI_B1S3_MASK: FMI bank 1 sector 3.
\r
452 * Return : The Protection Status of the needed sector.
\r
453 * - RESET: The needed sector is not write protected.
\r
454 * - SET : The needed sector is write protected.
\r
455 *******************************************************************************/
\r
456 FlagStatus FMI_GetWriteProtectionStatus(u32 FMI_Sector_Mask)
\r
458 u16 Protection_Level_1_Register = 0;
\r
459 /* Write a read flash protection level 1 register command */
\r
460 *(vu16 *)FMI_BANK_1 = 0x90;
\r
462 /* Read the flash protection level 1 register */
\r
463 Protection_Level_1_Register = *(vu16 *)(FMI_BANK_1 + 0x10);
\r
465 /* Write a read array command */
\r
466 *(vu16 *)FMI_BANK_1 = 0xFF;
\r
468 if (Protection_Level_1_Register &= FMI_Sector_Mask)
\r
478 /*******************************************************************************
\r
479 * Function Name : FMI_WaitForLastOperation
\r
480 * Description : Wait until the last operation (Write halfword, Write OTP
\r
481 * halfword, Erase sector and Erase bank) completion.
\r
482 * Input : FMI_Bank: specifies the bank where the operation is on going.
\r
483 * This parameter can be one of the following values:
\r
484 * - FMI_BANK_0: FMI bank 0.
\r
485 * - FMI_BANK_1: FMI bank 1.
\r
487 * Return : The timeout status.
\r
488 * This parameter can be one of the following values:
\r
489 * - FMI_TIME_OUT_ERROR: Timeout error occurred.
\r
490 * - FMI_NO_TIME_OUT_ERROR: No timeout error.
\r
491 *******************************************************************************/
\r
492 u8 FMI_WaitForLastOperation(vu32 FMI_Bank)
\r
496 /* Write a read status register command */
\r
497 *(vu16 *)(FMI_Bank) = 0x70;
\r
499 /* Wait until operation compeletion */
\r
500 while((!((*(vu16 *)FMI_Bank) & 0x80))&&(Time_Out < TIMEOUT ))
\r
502 Time_Out ++; /* Time Out */
\r
505 /* Write a read array command */
\r
506 *(vu16 *)FMI_Bank = 0xFF;
\r
508 if (Time_Out == TIMEOUT)
\r
510 return FMI_TIME_OUT_ERROR;
\r
514 return FMI_NO_TIME_OUT_ERROR;
\r
519 /******************* (C) COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/
\r