1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file drvPARFLASH.c
98 /// @brief Parallel Flash Driver Interface
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101
102
103 //-------------------------------------------------------------------------------------------------
104 // Include Files
105 //-------------------------------------------------------------------------------------------------
106 #include <stdio.h>
107 #include <string.h>
108
109 // Common Definition
110 #include "MsCommon.h"
111 #include "drvPARFLASH.h"
112 #include "MsOS.h"
113
114 // Internal Definition
115 #include "regPARFLASH.h"
116 #include "halPARFLASH.h"
117
118 #include "drvMMIO.h"
119
120 //-------------------------------------------------------------------------------------------------
121 // Driver Compiler Options
122 //-------------------------------------------------------------------------------------------------
123
124 //-------------------------------------------------------------------------------------------------
125 // Local Defines
126 //-------------------------------------------------------------------------------------------------
127 // TODO: Review OS and non-OS API
128 #if defined (MSOS_TYPE_NOS)
129 #define MsOS_CreateMutex(a, b, c) 1
130 #define MsOS_In_Interrupt() FALSE
131 #define MsOS_ObtainMutex(a, b) TRUE
132 #define MsOS_ReleaseMutex(a)
133 #endif
134
135 //--- Mxic --------//
136 #define PF_MAIC_MANUFACTURE_ID 0xC2
137 #define PF_MX29GLSERIES_0 0x7E
138 #define PF_MX29GLSERIES_1 0x01
139 #define PF_MX29LV400CT 0xB9
140 #define PF_MX29LV400CB 0xBA
141 #define PF_MX29LV800CT 0xDA
142 #define PF_MX29LV800CB 0x5B
143 #define PF_MX29LV160CT 0xC4
144 #define PF_MX29LV160CB 0x49
145 #define PF_MX29LV640BT 0xC9
146 #define PF_MX29LV640BB 0xCB
147 #define PF_MX29GL256EH 0x22
148 #define PF_MX29GA256E_SERIES 0x38
149 #define PF_MX29GA128E_SERIES 0x37
150 #define PF_MX29GAXXXE_H 0x10 //bit 4
151 #define PF_MX29GAXXXE_L 0x00 //bit 4
152
153 //---- Spansion -----//
154 #define PF_SPAN_MANUFACTURE_ID 0x01
155 #define PF_SPAN_S29SERIES_0 0x227E
156 #define PF_SPAN_S29GL128P 0x2221
157 #define PF_SPAN_S29GL256P 0x2222
158 #define PF_SPAN_S29GL512P 0x2223
159 #define PF_SPAN_S29GL01GP 0x2228
160 #define PF_SPAN_S29GL128P_S 0x2237
161 #define PF_SPAN_S29GL256P_S 0x2238
162 #define PF_SPAN_S29GL512P_S 0x2239
163 #define PF_SPAN_S29GL01GP_S 0x2240
164 #define PF_SPAN_S29SERIES_1 0x2201
165
166 //------------ Commends ----------------------
167 #define PFSH_CMD0 0xAA
168 #define PFSH_CMD1 0x55
169 #define PFSHF_CMD_RID 0x90
170 #define PFSH_CMD_ERASE 0x80
171 #define PFSH_CMD_CE 0x10
172 #define PFSH_CMD_SE 0x30
173 #define PFSH_CMD_PA 0xA0
174 #define PFSH_CMD_RESET 0xF0
175 #define PFSH_CMD_CFI_READ 0x98
176
177 #define PFSH_CMDADDR0 0xAAA
178 #define PFSH_CMDADDR1 0x555
179 #define PFSH_DEVID_ADDR1 0x02
180 #define PFSH_DEVID_ADDR2 0x1C
181 #define PFSH_DEVID_ADDR3 0x1E
182 #define PFSH_SECUREDID_ADDR 0x06
183 #define PFSH_SECPROVER_ADDR 0x04
184
185 //serial flash mutex wait time
186 #define PARFLASH_MUTEX_WAIT_TIME 3000
187 #define SERFLASH_SAFETY_FACTOR 10
188
189
190 //-------------------------------------------------------------------------------------------------
191 // Local Structurs
192 //-------------------------------------------------------------------------------------------------
193 typedef struct
194 {
195 MS_U16 u16CmdAdd0;
196 MS_U16 u16CmdAdd1;
197 MS_U16 u16DevIDAdd1;
198 MS_U16 u16DevIDAdd2;
199 MS_U16 u16DevIDAdd3;
200 MS_U16 u16SecProVerAddr;
201 }PARFLASH_CmdAddr_List;
202
203
204 //-------------------------------------------------------------------------------------------------
205 // Global Variables
206 //-------------------------------------------------------------------------------------------------
207
208
209 //-------------------------------------------------------------------------------------------------
210 // Extern function
211 //-------------------------------------------------------------------------------------------------
212
213
214 //-------------------------------------------------------------------------------------------------
215 // Local Variables
216 //-------------------------------------------------------------------------------------------------
217 static MSIF_Version _drv_norf_version = {
218 .DDI = { NORF_DRV_VERSION },
219 };
220
221 //---- The sector table of fisrt 64K -----
222 // Array[0]: number of sectors
223 // Array[1] ~ Array[n]: sector size, unit is 1K bytes
224 //-----------------------------------------------------------
225 static MS_U8 _MX29LV400CB_SECTBL_64K[] = { 4, 16, 8, 8, 32};
226 static MS_U8 _MX29LV640BT_SECTBL_64K[] = { 8, 8, 8, 8, 8, 8, 8, 8, 8};
227 //----------------------------------------------------------
228
229 //TopBoot,unifirmSec, SecNum, ByteSize, SecTblPtr
230 static PARFLASH_Content _drv_pf_content[] =
231 {
232 { 1, 0, 11, 0x80000, _MX29LV400CB_SECTBL_64K }, //512K //PF_MX29LV400CT
233 { 0, 0, 11, 0x80000, _MX29LV400CB_SECTBL_64K }, //512K //PF_MX29LV400CB
234 { 1, 0, 19, 0x100000, _MX29LV400CB_SECTBL_64K }, //1M //PF_MX29LV800CT
235 { 0, 0, 19, 0x100000, _MX29LV400CB_SECTBL_64K }, //1M //PF_MX29LV800CB
236 { 1, 0, 35, 0x200000, _MX29LV400CB_SECTBL_64K }, //2M //PF_MX29LV160CT
237 { 0, 0, 35, 0x200000, _MX29LV400CB_SECTBL_64K }, //2M //PF_MX29LV160CB
238 { 1, 0, 135, 0x800000, _MX29LV640BT_SECTBL_64K }, //8M //PF_MX29LV640BT
239 { 0, 0, 135, 0x800000, _MX29LV640BT_SECTBL_64K }, //8M //PF_MX29LV640BB
240 { 0, 1, 256, 0x2000000, 0 }, //32M //PF_MX29GL256EH
241 { 0, 1, 128, 0x2000000, 0 }, //32M //PF_MX29GA128EL
242 { 0, 1, 128, 0x2000000, 0 }, //32M //PF_MX29GA128EH
243 { 0, 1, 256, 0x2000000, 0 }, //32M //PF_MX29GA256EL
244 { 0, 1, 256, 0x2000000, 0 }, //32M //PF_MX29GA256EH
245
246 { 0, 1, 128, 0x1000000, 0 }, //16M //PF_SPAN_S29GL128P
247 { 0, 1, 256, 0x2000000, 0 }, //32M //PF_SPAN_S29GL256P
248 { 0, 1, 512, 0x4000000, 0 }, //64M //PF_SPAN_S29GL512P
249 { 0, 1, 1024, 0x8000000, 0 }, //64M //PF_SPAN_S29GL01GP
250
251 { 0, 1, 128, 0x1000000, 0 }, //16M //PF_SPAN_S29GL128P_S
252 { 0, 1, 256, 0x2000000, 0 }, //32M //PF_SPAN_S29GL256P_S
253 { 0, 1, 512, 0x4000000, 0 }, //64M //PF_SPAN_S29GL512P_S
254
255
256 };
257
258 //default value is word mode commend
259 static PARFLASH_CmdAddr_List _pfsh_cmdaddr_list =
260 {
261 .u16CmdAdd0 = PFSH_CMDADDR0,
262 .u16CmdAdd1 = PFSH_CMDADDR1,
263 .u16DevIDAdd1 = PFSH_DEVID_ADDR1,
264 .u16DevIDAdd2 = PFSH_DEVID_ADDR2,
265 .u16DevIDAdd3 = PFSH_DEVID_ADDR3,
266 .u16SecProVerAddr = PFSH_SECPROVER_ADDR,
267 };
268
269 static PARFLASH_Info _ParFlashInfo =
270 {
271 .enDevice = evPF_NUM,
272 .bbytemode = 0,
273 .u16SecNum = 0,
274 .u32TotBytes = 0,
275 };
276
277 static MS_U32 _u32pfsh_CmdAddAry[PFSH_MAX_CMDRUN];
278 static MS_U16 _u16pfsh_CmdDataAry[PFSH_MAX_CMDRUN];
279
280 static MS_S32 _s32ParFlash_Mutex;
281 static PARFLASH_DevSts _ParFlashDrvStatus;
282
283 static MS_U8 _u81KSecTblShift = 9;
284
285 //-------------------------------------------------------------------------------------------------
286 // Debug Functions
287 //-------------------------------------------------------------------------------------------------
288
289
290 //-------------------------------------------------------------------------------------------------
291 // Local Functions
292 //-------------------------------------------------------------------------------------------------
293
294 //if byte mode, return byte size; if word mode, return word size
_Drv_PARFLASH_GetSectorSize(MS_U16 u16sector)295 static MS_U32 _Drv_PARFLASH_GetSectorSize(MS_U16 u16sector)
296 {
297 MS_U32 u32size = 64;
298 MS_U8* pu8tr = 0;
299 MS_U16 u16temp;
300
301 if(_ParFlashInfo.enDevice >= evPF_NUM)
302 {
303 printf("_ParFlashInfo.enDevice is invalid\n");
304 return 0;
305 }
306
307 if(_drv_pf_content[_ParFlashInfo.enDevice].bUniformSecTbl)
308 {
309 u32size <<= (MS_U32)(_u81KSecTblShift & 0xFF);
310 return u32size;
311 }
312
313 pu8tr = _drv_pf_content[_ParFlashInfo.enDevice].pu8SecTbl;
314 if(_drv_pf_content[_ParFlashInfo.enDevice].bTopBoot)
315 {
316 if(u16sector >= (_drv_pf_content[_ParFlashInfo.enDevice].u16SecNum - (MS_U16)(pu8tr[0] & 0xFF)))
317 {
318 u16temp = (MS_U16)(pu8tr[0] & 0xFF) - _drv_pf_content[_ParFlashInfo.enDevice].u16SecNum - u16sector + 1;
319 u32size = (MS_U32)(pu8tr[u16temp] & 0xFF);
320 }
321 }
322 else
323 {
324 if(u16sector < (MS_U16)(pu8tr[0] & 0xFF))
325 u32size = (MS_U32)(pu8tr[++u16sector] & 0xFF);
326 }
327 u32size <<= (MS_U32)_u81KSecTblShift;
328
329 return u32size;
330 }
331
332 //if byte mode, return byte offset; if word mode, return word offset
_Drv_PARFLASH_GetSectorOffset(MS_U16 u16sector)333 static MS_U32 _Drv_PARFLASH_GetSectorOffset(MS_U16 u16sector)
334 {
335 MS_U32 u32SecOffset = 0;
336 MS_U8* pu8tr = 0;
337 MS_U16 u16LastUnif, u16ii = 0;
338
339 if(_ParFlashInfo.enDevice >= evPF_NUM)
340 return 0xFFFFFFFF;
341
342 if(_drv_pf_content[_ParFlashInfo.enDevice].bUniformSecTbl)
343 {
344 u32SecOffset = (u16sector << 6) << _u81KSecTblShift; //64K sector
345 return u32SecOffset;
346 }
347
348 pu8tr = _drv_pf_content[_ParFlashInfo.enDevice].pu8SecTbl;
349 if(_drv_pf_content[_ParFlashInfo.enDevice].bTopBoot)
350 {
351 u16LastUnif = _drv_pf_content[_ParFlashInfo.enDevice].u16SecNum - (MS_U16)(pu8tr[0] & 0xFF) - 1;
352 //caclulate uniform sector
353 if(u16sector <= u16LastUnif)
354 u16ii = u16sector;
355 else
356 u16ii = u16LastUnif;
357 u32SecOffset = (MS_U32)(u16ii & 0xFFFF) << 6; //64K sector
358 //caclulate un-uniform sector
359 while(++u16ii <= u16sector)
360 u32SecOffset += pu8tr[u16ii - u16LastUnif];
361 }
362 else
363 {
364 //caclulate un-uniform sector
365 while((u16ii < u16sector) && (u16ii < (MS_U16)(pu8tr[0] & 0xFF)))
366 u32SecOffset += (MS_U32)(pu8tr[++u16ii] & 0xFF);
367 //caclulate uniform sector
368 if(u16ii < u16sector)
369 u32SecOffset += ((MS_U32)((u16sector - u16ii) & 0xFFFF) << 6); //64K sector
370 }
371
372 return (u32SecOffset << _u81KSecTblShift);
373 }
374 //--- for future using -----
375 #if 0
376 static MS_U16 _Drv_PARFLASH_GetSectorIndex(MS_U32 u32addr)
377 {
378 MS_U16 u16SecIdx = 0;
379 MS_U8* pu8tr = 0, u8ii;
380 MS_U32 u32UnUnitOffset, u32Offset = 0;
381
382 if(_ParFlashInfo.enDevice >= evPF_NUM)
383 return 0xFFFF;
384
385 if(_drv_pf_content[_ParFlashInfo.enDevice].bUniformSecTbl)
386 {
387 u16SecIdx = (MS_U16)((u32addr >> (MS_U32)(_u81KSecTblShift & 0xFF)) >> 6);
388 return u16SecIdx;
389 }
390
391 pu8tr = _drv_pf_content[_ParFlashInfo.enDevice].pu8SecTbl;
392 for(u8ii = 1; u8ii <= pu8tr[0]; u8ii++)
393 u32UnUnitOffset = (MS_U32)(pu8tr[u8ii] & 0xFF) << (MS_U32)(_u81KSecTblShift & 0xFF);
394
395 //uniform sector
396 if(_drv_pf_content[_ParFlashInfo.enDevice].bTopBoot)
397 {
398 if(_ParFlashInfo.bbytemode)
399 u32UnUnitOffset = _ParFlashInfo.u32TotBytes - u32UnUnitOffset;
400 else
401 u32UnUnitOffset = (_ParFlashInfo.u32TotBytes >> 1) - u32UnUnitOffset;
402 if(u32addr <= u32UnUnitOffset)
403 {
404 u16SecIdx = (u32addr >> (MS_U32)(_u81KSecTblShift & 0xFF)) >> 6;
405 return u16SecIdx;
406 }
407 else
408 u16SecIdx = (u32UnUnitOffset >> (MS_U32)(_u81KSecTblShift & 0xFF)) >> 6;
409 }
410 else
411 {
412 if(u32addr >= u32UnUnitOffset)
413 {
414 u16SecIdx = (MS_U16)(pu8tr[0] & 0xFF);
415 u16SecIdx += (((u32addr - u32UnUnitOffset) >> (MS_U32)(_u81KSecTblShift & 0xFF)) >> 6);
416 return u16SecIdx;
417 }
418 }
419
420 //un-uniform sector
421 for(u8ii = 1; u8ii <= pu8tr[0]; u8ii++)
422 {
423 if(u32addr >= u32Offset)
424 break;
425 u32Offset += ((MS_U32)(pu8tr[u8ii] & 0xFF) << (MS_U32)(_u81KSecTblShift & 0xFF));
426 u16SecIdx++;
427 }
428
429 return u16SecIdx;
430 }
431 #endif
432
_Drv_PARFLASH_Reset(void)433 static MS_BOOL _Drv_PARFLASH_Reset(void)
434 {
435 _u32pfsh_CmdAddAry[3] = 0;
436 _u16pfsh_CmdDataAry[3] = PFSH_CMD_RESET;
437
438 if(!HAL_PARFLASH_Cmd_Write(1, &(_u32pfsh_CmdAddAry[3]), &(_u16pfsh_CmdDataAry[3]))) //1 runs, direct mode
439 return FALSE;
440
441 return TRUE;
442 }
443
_Drv_PARFLASH_Toggle(MS_U32 u32dst)444 static MS_BOOL _Drv_PARFLASH_Toggle(MS_U32 u32dst)
445 {
446 MS_U16 u16data, u16data2;
447 MS_BOOL bresult = FALSE;
448
449 while (TRUE)
450 {
451 if(!HAL_PARFLASH_Read(u32dst, &u16data))
452 return FALSE;
453 if(!HAL_PARFLASH_Read(u32dst, &u16data2))
454 return FALSE;
455 //printf("tog 0 %x %x\n", u16data, u16data2);
456
457 if ((u16data&0x40) != (u16data2&0x40)) //Q6 toggleing
458 {
459 if ((u16data2 & 0x20) == 0x20) // Q5 is 1, exceed time limit
460 {
461 if(!HAL_PARFLASH_Read(u32dst, &u16data))
462 return FALSE;
463 if(!HAL_PARFLASH_Read(u32dst, &u16data2))
464 return FALSE;
465
466 if ((u16data&0x40) != (u16data2&0x40)) //Q6 toggleing
467 {
468 _Drv_PARFLASH_Reset(); // Toggle bit algorithm exceed time limit
469 return FALSE;;
470 }
471 else
472 {
473 return TRUE; // Stop toggle.
474 }
475 }
476 }
477 else
478 {
479 return TRUE;
480 }
481 }
482
483 return bresult;
484 }
485
_Drv_PARFLASH_ReadID(MS_U32 u32IDAddr,MS_U16 * pu16ID)486 static MS_BOOL _Drv_PARFLASH_ReadID(MS_U32 u32IDAddr, MS_U16* pu16ID)
487 {
488 *pu16ID = 0;
489
490 _u32pfsh_CmdAddAry[2] = _pfsh_cmdaddr_list.u16CmdAdd0;
491 _u16pfsh_CmdDataAry[2] = PFSHF_CMD_RID;
492
493 //read ID
494 if(!HAL_PARFLASH_Cmd_Write(3, _u32pfsh_CmdAddAry, _u16pfsh_CmdDataAry)) //3 runs, direct mode
495 return FALSE;
496
497 if(!HAL_PARFLASH_Read(u32IDAddr, pu16ID))
498 return FALSE;
499
500 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("ID addr %x, data %04x\n", (unsigned int)u32IDAddr, (unsigned short)(*pu16ID)));
501
502 if(!_Drv_PARFLASH_Reset())
503 return FALSE;
504
505 return TRUE;
506 }
507
508 //-------------------------------------------------------------------------------------------------
509 // Global Functions
510 //-------------------------------------------------------------------------------------------------
511
512 //-------------------------------------------------------------------------------------------------
513 /// Get the information of Parallel Flash
514 /// @return the pointer to the driver information
515 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_GetInfo(void)516 const PARFLASH_Info *MDrv_PARFLASH_GetInfo(void)
517 {
518 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO,\
519 printf("MDrv_PARFLASH_GetInfo()\n\
520 \tenDevice = %d\n\
521 \tbbytemode = %d\n\
522 \tu16SecNum = %d\n\
523 \tu32TotBytes = %d\n",\
524 (int)(_ParFlashInfo.enDevice),
525 (int)(_ParFlashInfo.bbytemode),
526 (int)(_ParFlashInfo.u16SecNum),
527 (int)(_ParFlashInfo.u32TotBytes)
528 )
529 );
530
531 return &_ParFlashInfo;
532 }
533
534 //------------------------------------------------------------------------------
535 /// Description: Show the NORF driver version
536 /// @param ppVersion \b OUT: output NORF driver version
537 /// @return TRUE : succeed
538 /// @return FALSE : failed
539 //------------------------------------------------------------------------------
MDrv_PARFLASH_GetLibVer(const MSIF_Version ** ppVersion)540 MS_BOOL MDrv_PARFLASH_GetLibVer(const MSIF_Version **ppVersion)
541 {
542 if (!ppVersion)
543 return FALSE;
544
545 *ppVersion = &_drv_norf_version;
546
547 return TRUE;
548 }
549
550 //------------------------------------------------------------------------------
551 /// Get Parallel Flash driver status
552 /// @param pDrvStatus \b OUT: poniter to store the returning driver status
553 /// @return TRUE : succeed
554 /// @return FALSE : failed to get the driver status
555 //------------------------------------------------------------------------------
MDrv_PARFLASH_GetStatus(PARFLASH_DevSts * pDrvStatus)556 MS_BOOL MDrv_PARFLASH_GetStatus(PARFLASH_DevSts* pDrvStatus)
557 {
558 memcpy(pDrvStatus, &_ParFlashDrvStatus, sizeof(_ParFlashDrvStatus));
559
560 return TRUE;
561 }
562
563
564 //------------------------------------------------------------------------------
565 /// Set detailed level of Parallel Flash driver debug message
566 /// @param u8DbgLevel \b IN debug level for Parallel Flash driver
567 /// @return TRUE : succeed
568 /// @return FALSE : failed to set the debug level
569 //------------------------------------------------------------------------------
MDrv_PARFLASH_SetDbgLevel(MS_U8 u8DbgLevel)570 MS_BOOL MDrv_PARFLASH_SetDbgLevel(MS_U8 u8DbgLevel)
571 {
572 _u8ParFlashDbgLevel = u8DbgLevel;
573
574 return TRUE;
575 }
576
577 //-------------------------------------------------------------------------------------------------
578 /// Initialize Parallel Flash
579 /// @return None
580 /// @note called only once at system initialization
581 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_Init(void)582 void MDrv_PARFLASH_Init(void)
583 {
584 MS_U32 u32NonPMBank, u32NonPMBankSize;
585 MS_U32 u32PMBank, u32PMBankSize;
586
587 _u8ParFlashDbgLevel = PARFLASH_DBGLV_INFO; // init debug level first
588
589 _s32ParFlash_Mutex = MsOS_CreateMutex(E_MSOS_FIFO, "Mutex ParFlash", MSOS_PROCESS_SHARED);
590 MS_ASSERT(_s32ParFlash_Mutex >= 0);
591
592 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s()\n", __FUNCTION__));
593
594 //
595 // 1. HAL init
596 //
597 if (!MDrv_MMIO_GetBASE( &u32NonPMBank, &u32NonPMBankSize, MS_MODULE_PFSH))
598 {
599 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("IOMap failure to get MS_MODULE_PFSH\n"));
600 u32NonPMBank = BASEADDR_RIU;
601 }
602 if (!MDrv_MMIO_GetBASE( &u32PMBank, &u32PMBankSize, MS_MODULE_PM))
603 {
604 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("IOMap failure to get MS_MODULE_PIU\n"));
605 u32PMBank = BASEADDR_RIU;
606 }
607 HAL_PARFLASH_Config(u32PMBank, u32NonPMBank);
608
609 HAL_PARFLASH_Init(&(_ParFlashInfo.bbytemode));
610
611 //
612 // 2. init other data structure of Parallel Flash driver
613 //
614 if(_ParFlashInfo.bbytemode)
615 {
616 _u81KSecTblShift = 10;
617 _pfsh_cmdaddr_list.u16CmdAdd0 = PFSH_CMDADDR0;
618 _pfsh_cmdaddr_list.u16CmdAdd1 = PFSH_CMDADDR1;
619 _pfsh_cmdaddr_list.u16DevIDAdd1 = PFSH_DEVID_ADDR1;
620 _pfsh_cmdaddr_list.u16DevIDAdd2 = PFSH_DEVID_ADDR2;
621 _pfsh_cmdaddr_list.u16DevIDAdd3 = PFSH_DEVID_ADDR3;
622 _pfsh_cmdaddr_list.u16SecProVerAddr = PFSH_SECPROVER_ADDR;
623 }
624 else
625 {
626 _u81KSecTblShift = 9;
627 _pfsh_cmdaddr_list.u16CmdAdd0 = PFSH_CMDADDR0 >> 1;
628 _pfsh_cmdaddr_list.u16CmdAdd1 = PFSH_CMDADDR1 >> 1;
629 _pfsh_cmdaddr_list.u16DevIDAdd1 = PFSH_DEVID_ADDR1 >> 1;
630 _pfsh_cmdaddr_list.u16DevIDAdd2 = PFSH_DEVID_ADDR2 >> 1;
631 _pfsh_cmdaddr_list.u16DevIDAdd3 = PFSH_DEVID_ADDR3 >> 1;
632 _pfsh_cmdaddr_list.u16SecProVerAddr = PFSH_SECPROVER_ADDR >> 1;
633 }
634
635 //-- init commend data array
636 _u32pfsh_CmdAddAry[0] = _pfsh_cmdaddr_list.u16CmdAdd0;
637 _u32pfsh_CmdAddAry[1] = _pfsh_cmdaddr_list.u16CmdAdd1;
638 _u16pfsh_CmdDataAry[0] = PFSH_CMD0;
639 _u16pfsh_CmdDataAry[1] = PFSH_CMD1;
640
641 _ParFlashDrvStatus.bIsBusy = FALSE;
642
643 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
644 }
645
646 //-------------------------------------------------------------------------------------------------
647 /// Select chip
648 /// @param u8cs \b IN: Flash index. value: 0~1
649 /// @return FALSE : fail before timeout or illegal parameters
650 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_ChipSelect(MS_U8 u8cs)651 MS_BOOL MDrv_PARFLASH_ChipSelect(MS_U8 u8cs)
652 {
653 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
654
655 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(%d)\n", __FUNCTION__, (int)u8cs));
656
657 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
658 {
659 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_ParFlash_Reset fails!\n"));
660 return FALSE;
661 }
662
663 _ParFlashInfo.bbytemode = HAL_PARFLASH_SelectChip(u8cs);
664
665 if(_ParFlashInfo.bbytemode)
666 {
667 _u81KSecTblShift = 10;
668 _pfsh_cmdaddr_list.u16CmdAdd0 = PFSH_CMDADDR0;
669 _pfsh_cmdaddr_list.u16CmdAdd1 = PFSH_CMDADDR1;
670 _pfsh_cmdaddr_list.u16DevIDAdd1 = PFSH_DEVID_ADDR1;
671 _pfsh_cmdaddr_list.u16DevIDAdd2 = PFSH_DEVID_ADDR2;
672 _pfsh_cmdaddr_list.u16DevIDAdd3 = PFSH_DEVID_ADDR3;
673 _pfsh_cmdaddr_list.u16SecProVerAddr = PFSH_SECPROVER_ADDR;
674 }
675 else
676 {
677 _u81KSecTblShift = 9;
678 _pfsh_cmdaddr_list.u16CmdAdd0 = PFSH_CMDADDR0 >> 1;
679 _pfsh_cmdaddr_list.u16CmdAdd1 = PFSH_CMDADDR1 >> 1;
680 _pfsh_cmdaddr_list.u16DevIDAdd1 = PFSH_DEVID_ADDR1 >> 1;
681 _pfsh_cmdaddr_list.u16DevIDAdd2 = PFSH_DEVID_ADDR2 >> 1;
682 _pfsh_cmdaddr_list.u16DevIDAdd3 = PFSH_DEVID_ADDR3 >> 1;
683 _pfsh_cmdaddr_list.u16SecProVerAddr = PFSH_SECPROVER_ADDR >> 1;
684 }
685
686 //-- init commend data array
687 _u32pfsh_CmdAddAry[0] = _pfsh_cmdaddr_list.u16CmdAdd0;
688 _u32pfsh_CmdAddAry[1] = _pfsh_cmdaddr_list.u16CmdAdd1;
689 _u16pfsh_CmdDataAry[0] = PFSH_CMD0;
690 _u16pfsh_CmdDataAry[1] = PFSH_CMD1;
691
692 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
693
694 return TRUE;
695 }
696
697 //-------------------------------------------------------------------------------------------------
698 /// Reset Parallel Flash
699 /// @return TRUE : succeed
700 /// @return FALSE : fail before timeout or illegal parameters
701 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_Reset(void)702 MS_BOOL MDrv_PARFLASH_Reset(void)
703 {
704 MS_BOOL bres = FALSE;
705
706 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
707
708 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s()\n", __FUNCTION__));
709
710 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
711 {
712 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_ParFlash_Reset fails!\n"));
713 return FALSE;
714 }
715
716 bres = _Drv_PARFLASH_Reset();
717
718 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
719
720 return bres;
721 }
722
723 //-------------------------------------------------------------------------------------------------
724 /// Read ID in Parallel Flash
725 /// @param pu16Data \b IN: ID data, max length is 4 words
726 /// @param pu8r_len \b IN: ID data count
727 /// @return TRUE : succeed
728 /// @return FALSE : fail before timeout or illegal parameters
729 /// @note Not allowed in interrupt context
730 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_ReadID(MS_U16 * pu16Data,MS_U8 * pu8r_len)731 MS_BOOL MDrv_PARFLASH_ReadID(MS_U16 *pu16Data, MS_U8 *pu8r_len)
732 {
733 MS_U16 u16data;
734 MS_BOOL bres = FALSE;
735 MS_U8 u8len = 0;
736
737 *pu8r_len = 0;
738
739 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
740
741 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(%p, %p)\n", __FUNCTION__, pu16Data, pu8r_len));
742
743 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
744 {
745 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_ReadID fails!\n"));
746 return FALSE;
747 }
748
749 //-- read manufacture ID -----
750 if(!(bres = _Drv_PARFLASH_ReadID(0, &u16data)))
751 goto END;
752 pu16Data[u8len++] = u16data;
753
754 //--- device id 1 ------
755 if(!(bres = _Drv_PARFLASH_ReadID((MS_U32)(_pfsh_cmdaddr_list.u16DevIDAdd1 & 0xFFFF), &u16data)))
756 goto END;
757 pu16Data[u8len++] = u16data;
758
759 if(pu16Data[0] == PF_SPAN_MANUFACTURE_ID ||
760 (pu16Data[0] == PF_MAIC_MANUFACTURE_ID && ((pu16Data[1] & 0xFF) == PF_MX29GLSERIES_0)))
761 {
762 //--- device id 2 ------
763 if(!(bres = _Drv_PARFLASH_ReadID((MS_U32)(_pfsh_cmdaddr_list.u16DevIDAdd2 & 0xFFFF), &u16data)))
764 goto END;
765 pu16Data[u8len++] = u16data;
766
767 //--- device id 3 ------
768 if(!(bres = _Drv_PARFLASH_ReadID((MS_U32)(_pfsh_cmdaddr_list.u16DevIDAdd3 & 0xFFFF), &u16data)))
769 goto END;
770 pu16Data[u8len++] = u16data;
771
772 //--- Secured Silicon ------
773 if(!(bres = _Drv_PARFLASH_ReadID((MS_U32)(PFSH_SECUREDID_ADDR & 0xFFFF), &u16data)))
774 goto END;
775 pu16Data[u8len++] = u16data;
776 }
777
778 _ParFlashInfo.enDevice = evPF_NUM; //unknown type
779 _ParFlashInfo.u16SecNum = 0;
780 _ParFlashInfo.u32TotBytes = 0;
781 if(pu16Data[0] == PF_MAIC_MANUFACTURE_ID)
782 {
783 switch((pu16Data[1] & 0xFF))
784 {
785 case PF_MX29LV400CT:
786 _ParFlashInfo.enDevice = enPF_MX29LV400CT;
787 _ParFlashInfo.u16SecNum = 11;
788 _ParFlashInfo.u32TotBytes = 524288;
789 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV400CT\n"));
790 break;
791 case PF_MX29LV400CB:
792 _ParFlashInfo.enDevice = enPF_MX29LV400CB;
793 _ParFlashInfo.u16SecNum = 11;
794 _ParFlashInfo.u32TotBytes = 524288;
795 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV400CB\n"));
796 break;
797 case PF_MX29LV800CT:
798 _ParFlashInfo.enDevice = enPF_MX29LV800CT;
799 _ParFlashInfo.u16SecNum = 19;
800 _ParFlashInfo.u32TotBytes = 1048576;
801 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV800CT\n"));
802 break;
803 case PF_MX29LV800CB:
804 _ParFlashInfo.enDevice = enPF_MX29LV800CB;
805 _ParFlashInfo.u16SecNum = 19;
806 _ParFlashInfo.u32TotBytes = 1048576;
807 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV800CB\n"));
808 break;
809 case PF_MX29LV160CT:
810 _ParFlashInfo.enDevice = enPF_MX29LV160CT;
811 _ParFlashInfo.u16SecNum = 35;
812 _ParFlashInfo.u32TotBytes = 2097152;
813 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV160CT\n"));
814 break;
815 case PF_MX29LV160CB:
816 _ParFlashInfo.enDevice = enPF_MX29LV160CB;
817 _ParFlashInfo.u16SecNum = 35;
818 _ParFlashInfo.u32TotBytes = 2097152;
819 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV160CB\n"));
820 break;
821 case PF_MX29LV640BT:
822 _ParFlashInfo.enDevice = enPF_MX29LV640BT;
823 _ParFlashInfo.u16SecNum = 135;
824 _ParFlashInfo.u32TotBytes = 0x800000;
825 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV640BT\n"));
826 break;
827 case PF_MX29LV640BB:
828 _ParFlashInfo.enDevice = enPF_MX29LV640BB;
829 _ParFlashInfo.u16SecNum = 256;
830 _ParFlashInfo.u32TotBytes = 0x2000000;
831 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29LV640BB\n"));
832 break;
833 case PF_MX29GLSERIES_0:
834 if((pu16Data[2] & 0xFF) == PF_MX29GL256EH)
835 {
836 _ParFlashInfo.enDevice = enPF_MX29GL256EH;
837 _ParFlashInfo.u16SecNum = 256;
838 _ParFlashInfo.u32TotBytes = 0x2000000;
839 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29GL256EH\n"));
840 }
841 else if((pu16Data[2] & 0xFF) == PF_MX29GA256E_SERIES)
842 {
843 if(pu16Data[3] & PF_MX29GAXXXE_H)
844 {
845 _ParFlashInfo.enDevice = enPF_MX29GA256EH;
846 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29GA256EH\n"));
847 }
848 else
849 {
850 _ParFlashInfo.enDevice = enPF_MX29GA256EL;
851 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29GA256EL\n"));
852 }
853 _ParFlashInfo.u16SecNum = 256;
854 _ParFlashInfo.u32TotBytes = 0x2000000;
855 }
856 else if((pu16Data[2] & 0xFF) == PF_MX29GA128E_SERIES)
857 {
858 if(pu16Data[3] & PF_MX29GAXXXE_H)
859 {
860 _ParFlashInfo.enDevice = enPF_MX29GA128EH;
861 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29GA128EH\n"));
862 }
863 else
864 {
865 _ParFlashInfo.enDevice = enPF_MX29GA128EL;
866 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MX29GA128EL\n"));
867 }
868 _ParFlashInfo.u16SecNum = 128;
869 _ParFlashInfo.u32TotBytes = 16777216;
870 }
871 else
872 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: PF_MX29GLSERIES_0 Unknown\n"));
873 break;
874 default:
875 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: MXIC Unkonown\n"));
876 break;
877 }
878 }
879 else if(pu16Data[0] == PF_SPAN_MANUFACTURE_ID)
880 {
881 if(pu16Data[1] == PF_SPAN_S29SERIES_0)
882 {
883 switch(pu16Data[2])
884 {
885 case PF_SPAN_S29GL128P:
886 _ParFlashInfo.enDevice = enPF_SPAN_S29GL128P;
887 _ParFlashInfo.u16SecNum = 128;
888 _ParFlashInfo.u32TotBytes = 16777216;
889 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL128P\n"));
890 break;
891 case PF_SPAN_S29GL256P:
892 _ParFlashInfo.enDevice = enPF_SPAN_S29GL256P;
893 _ParFlashInfo.u16SecNum = 256;
894 _ParFlashInfo.u32TotBytes = 33554432;
895 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL256P\n"));
896 break;
897 case PF_SPAN_S29GL512P:
898 _ParFlashInfo.enDevice = enPF_SPAN_S29GL512P;
899 _ParFlashInfo.u16SecNum = 512;
900 _ParFlashInfo.u32TotBytes = 67108864;
901 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL512P\n"));
902 break;
903 case PF_SPAN_S29GL01GP:
904 _ParFlashInfo.enDevice = enPF_SPAN_S29GL01GP;
905 _ParFlashInfo.u16SecNum = 1024;
906 _ParFlashInfo.u32TotBytes = 134217728;
907 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL01GP\n"));
908 break;
909 case PF_SPAN_S29GL128P_S:
910 _ParFlashInfo.enDevice = enPF_SPAN_S29GL128P_S;
911 _ParFlashInfo.u16SecNum = 128;
912 _ParFlashInfo.u32TotBytes = 16777216;
913 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL128P_S\n"));
914 break;
915 case PF_SPAN_S29GL256P_S:
916 _ParFlashInfo.enDevice = enPF_SPAN_S29GL256P_S;
917 _ParFlashInfo.u16SecNum = 256;
918 _ParFlashInfo.u32TotBytes = 33554432;
919 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL256P_S\n"));
920 break;
921 case PF_SPAN_S29GL512P_S:
922 _ParFlashInfo.enDevice = enPF_SPAN_S29GL512P_S;
923 _ParFlashInfo.u16SecNum = 512;
924 _ParFlashInfo.u32TotBytes = 67108864;
925 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: S29GL512P_S\n"));
926
927 break;
928 default:
929 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: SPANSION S29SERIES Unknown\n"));
930 break;
931 }
932 }
933 else
934 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: SPANSION Unknown\n"));
935 }
936 else
937 DEBUG_PAR_FLASH(PARFLASH_DBGLV_INFO, printf("Nor Flash: Unknown\n"));
938
939 *pu8r_len = u8len;
940
941 bres = TRUE;
942
943 END:
944
945 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
946
947 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("PFSH ID (%d): %04x %04x %04x %04x\n",
948 (int)(*pu8r_len & 0xFF), pu16Data[0], pu16Data[1], pu16Data[2], pu16Data[3]));
949
950 return bres;
951 }
952
953 //-------------------------------------------------------------------------------------------------
954 /// Read Sector protect condition
955 /// @param u16sec \b IN: Sector index
956 /// @param pbProtect \b Out: BOOL point to store protect condition.
957 /// @return TRUE : succeed
958 /// @return FALSE : fail before timeout or illegal parameters
959 /// @note Not allowed in interrupt context
960 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_SectorProtectVerify(MS_U16 u16sec,MS_BOOL * pbProtect)961 MS_BOOL MDrv_PARFLASH_SectorProtectVerify(MS_U16 u16sec, MS_BOOL* pbProtect)
962 {
963 MS_BOOL bres = FALSE;
964 MS_U16 u16data;
965 MS_U32 u32secaddr;
966
967 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
968
969 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(%04x, %p)\n", __FUNCTION__, u16sec, pbProtect));
970
971 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
972 {
973 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_ParFlash_ReadID fails!\n"));
974 return FALSE;
975 }
976
977 u32secaddr = _Drv_PARFLASH_GetSectorOffset(u16sec) | (MS_U32)(_pfsh_cmdaddr_list.u16SecProVerAddr & 0xFFFF);
978
979 //-- read manufacture ID -----
980 if(!(bres = _Drv_PARFLASH_ReadID(u32secaddr, &u16data)))
981 goto END;
982
983 *pbProtect = (MS_BOOL)u16data;
984
985 bres = TRUE;
986
987 END:
988
989 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
990
991 return bres;
992 }
993
994 //-------------------------------------------------------------------------------------------------
995 /// Read Sector protect condition
996 /// @param u8addr \b IN: CFI read address
997 /// @param pu16data \b IN: pointer to store CFI read data
998 /// @return TRUE : succeed
999 /// @return FALSE : fail before timeout or illegal parameters
1000 /// @note Not allowed in interrupt context
1001 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_CFI_Read(MS_U8 u8addr,MS_U16 * pu16data)1002 MS_BOOL MDrv_PARFLASH_CFI_Read(MS_U8 u8addr, MS_U16* pu16data)
1003 {
1004 MS_BOOL bres = FALSE;
1005
1006 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
1007
1008 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(%02x, %p)\n", __FUNCTION__, u8addr, pu16data));
1009
1010 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
1011 {
1012 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_ReadID fails!\n"));
1013 return FALSE;
1014 }
1015
1016 _u32pfsh_CmdAddAry[2] = (MS_U32)(_pfsh_cmdaddr_list.u16CmdAdd0 & 0xFF);
1017 _u16pfsh_CmdDataAry[2] = PFSH_CMD_CFI_READ;
1018
1019 if(!(bres = HAL_PARFLASH_Cmd_Write(1, &(_u32pfsh_CmdAddAry[2]), &(_u16pfsh_CmdDataAry[2]))))
1020 goto END;
1021
1022 if(!HAL_PARFLASH_Read((MS_U32)(u8addr & 0xFF), pu16data))
1023 goto END;
1024
1025 bres = _Drv_PARFLASH_Reset();
1026
1027 END:
1028
1029 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
1030
1031 return bres;
1032 }
1033
1034
1035 //-------------------------------------------------------------------------------------------------
1036 /// Erase all sectors in Parallel Flash
1037 /// @return TRUE : succeed
1038 /// @return FALSE : fail before timeout
1039 /// @note Not allowed in interrupt context
1040 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_EraseChip(void)1041 MS_BOOL MDrv_PARFLASH_EraseChip(void)
1042 {
1043 MS_BOOL bres = FALSE;
1044
1045 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
1046
1047 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s()\n", __FUNCTION__));
1048
1049 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
1050 {
1051 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_EraseSec fails!\n"));
1052 return FALSE;
1053 }
1054
1055 _u32pfsh_CmdAddAry[2] = _pfsh_cmdaddr_list.u16CmdAdd0;
1056 _u16pfsh_CmdDataAry[2] = PFSH_CMD_ERASE;
1057 _u32pfsh_CmdAddAry[3] = _pfsh_cmdaddr_list.u16CmdAdd0;
1058 _u16pfsh_CmdDataAry[3] = PFSH_CMD0;
1059 _u32pfsh_CmdAddAry[4] = _pfsh_cmdaddr_list.u16CmdAdd1;
1060 _u16pfsh_CmdDataAry[4] = PFSH_CMD1;
1061 _u32pfsh_CmdAddAry[5] = _pfsh_cmdaddr_list.u16CmdAdd0;
1062 _u16pfsh_CmdDataAry[5] = PFSH_CMD_CE;
1063
1064 if(!(bres = HAL_PARFLASH_Cmd_Write(6, _u32pfsh_CmdAddAry, _u16pfsh_CmdDataAry)))
1065 goto END;
1066
1067 bres = _Drv_PARFLASH_Toggle(0);
1068
1069 END:
1070
1071 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
1072
1073 return TRUE ;
1074 }
1075
1076 //-------------------------------------------------------------------------------------------------
1077 /// Erase certain sectors in Parallel Flash
1078 /// @param u16StartSec \b IN: start sector
1079 /// @param u16EndSec \b IN: end sector
1080 /// @return TRUE : succeed
1081 /// @return FALSE : fail before timeout or illegal parameters
1082 /// @note Not allowed in interrupt context
1083 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_EraseSec(MS_U16 u16StartSec,MS_U16 u16EndSec)1084 MS_BOOL MDrv_PARFLASH_EraseSec(MS_U16 u16StartSec, MS_U16 u16EndSec)
1085 {
1086 MS_BOOL bres = FALSE;
1087 MS_U16 u16loop;
1088
1089 if(_ParFlashInfo.enDevice >= evPF_NUM)
1090 return false;
1091
1092 if ( u16StartSec > u16EndSec || u16EndSec >= _drv_pf_content[_ParFlashInfo.enDevice].u16SecNum)
1093 {
1094 return FALSE;
1095 }
1096
1097 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
1098
1099 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(0x%04X, 0x%04X)\n", __FUNCTION__, (int)u16StartSec, (int)u16EndSec));
1100
1101 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
1102 {
1103 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_EraseSec fails!\n"));
1104 return FALSE;
1105 }
1106
1107 _u32pfsh_CmdAddAry[2] = _pfsh_cmdaddr_list.u16CmdAdd0;
1108 _u16pfsh_CmdDataAry[2] = PFSH_CMD_ERASE;
1109 _u32pfsh_CmdAddAry[3] = _pfsh_cmdaddr_list.u16CmdAdd0;
1110 _u16pfsh_CmdDataAry[3] = PFSH_CMD0;
1111 _u32pfsh_CmdAddAry[4] = _pfsh_cmdaddr_list.u16CmdAdd1;
1112 _u16pfsh_CmdDataAry[4] = PFSH_CMD1;
1113 _u32pfsh_CmdAddAry[5] = 0;
1114 _u16pfsh_CmdDataAry[5] = PFSH_CMD_SE;
1115
1116 for (u16loop = u16StartSec; u16loop <= u16EndSec; u16loop++)
1117 {
1118 _u32pfsh_CmdAddAry[5] = _Drv_PARFLASH_GetSectorOffset(u16loop);
1119
1120 if(!(bres = HAL_PARFLASH_Cmd_Write(6, _u32pfsh_CmdAddAry, _u16pfsh_CmdDataAry)))
1121 goto END;
1122 if(!(bres = _Drv_PARFLASH_Toggle(_u32pfsh_CmdAddAry[5])))
1123 goto END;
1124 }
1125
1126 bres = TRUE;
1127
1128 END:
1129
1130 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
1131
1132 return bres ;
1133 }
1134
1135 //-------------------------------------------------------------------------------------------------
1136 /// Write data to Parallel Flash
1137 /// @param u32Addr \b IN: start address (4-B aligned)
1138 /// @param pu8Data \b IN: data to be written (2-B aligned)
1139 /// @param u32Size \b IN: size in Bytes (4-B aligned)
1140 /// @return TRUE : succeed
1141 /// @return FALSE : fail before timeout or illegal parameters
1142 /// @note Not allowed in interrupt context
1143 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_Write(MS_U32 u32Addr,MS_U8 * pu8Data,MS_U32 u32Size)1144 MS_BOOL MDrv_PARFLASH_Write(MS_U32 u32Addr, MS_U8 *pu8Data, MS_U32 u32Size)
1145 {
1146 MS_BOOL bRet = FALSE;
1147 MS_U32 u32ii, u32Satrt;
1148 MS_U16 u16temp;
1149 MS_U8* pu8tr = pu8Data;
1150
1151 MS_ASSERT(u32Addr+u32Size <= _ParFlashInfo.u32TotBytes);
1152 MS_ASSERT(u32Addr%4 == 0);
1153 MS_ASSERT(u32Size%4 == 0);
1154 MS_ASSERT(u32Size >= 4);
1155 MS_ASSERT((MS_U32)pu8Data%2 == 0);
1156
1157 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
1158
1159 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(0x%08x,%p,%d)\n", __FUNCTION__, (unsigned int)u32Addr, (void*)pu8Data,(int)u32Size));
1160
1161 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
1162 {
1163 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_Write fails!\n"));
1164 return FALSE;
1165 }
1166
1167 _u32pfsh_CmdAddAry[2] = _pfsh_cmdaddr_list.u16CmdAdd0;
1168 _u16pfsh_CmdDataAry[2] = PFSH_CMD_PA;
1169
1170 if(!HAL_PARFLASH_PrepareCmdWrite(3, _u32pfsh_CmdAddAry, _u16pfsh_CmdDataAry))
1171 goto END;
1172
1173 u32Satrt = u32Addr;
1174 if(!_ParFlashInfo.bbytemode)
1175 u32Satrt >>= 1;
1176 for(u32ii = 0; u32ii < u32Size; u32ii++)
1177 {
1178 u16temp = (MS_U16)(*pu8tr & 0xFF);
1179 if(!_ParFlashInfo.bbytemode)
1180 {
1181 u32ii++;
1182 pu8tr++;
1183 u16temp |= ((MS_U16)(*pu8tr & 0xFF) << 8);
1184 }
1185 //printf("write data (%d): %04x\n", (unsigned int)u32Satrt, u16temp);
1186 if(!HAL_PARFLASH_LastCmdTrig(4, u32Satrt, u16temp))
1187 goto END;
1188
1189 if(!_Drv_PARFLASH_Toggle(u32Satrt))
1190 goto END;
1191
1192 pu8tr++;
1193 u32Satrt++;
1194 }
1195
1196 bRet = TRUE;
1197
1198 END:
1199 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
1200
1201 return bRet;
1202 }
1203
1204 //-------------------------------------------------------------------------------------------------
1205 /// Read data from Parallel Flash
1206 /// @param u32Addr \b IN: start address (4-B aligned)
1207 /// @param pu8Data \b OUT: data ptr to store the read data (2-B aligned)
1208 /// @param u32Size \b IN: size in Bytes (4-B aligned)
1209 /// @return TRUE : succeed
1210 /// @return FALSE : fail before timeout or illegal parameters
1211 /// @note Not allowed in interrupt context
1212 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_Read(MS_U32 u32Addr,MS_U8 * pu8Data,MS_U32 u32Size)1213 MS_BOOL MDrv_PARFLASH_Read(MS_U32 u32Addr, MS_U8 *pu8Data, MS_U32 u32Size)
1214 {
1215 MS_BOOL bRet = FALSE;
1216 MS_U32 u32ii, u32Satrt;
1217 MS_U16 u16temp;
1218 MS_U8* pu8tr = pu8Data;
1219
1220 MS_ASSERT(u32Addr+u32Size <= _ParFlashInfo.u32TotBytes);
1221 MS_ASSERT(u32Addr%4 ==0);
1222 MS_ASSERT(u32Size%4 ==0);
1223 MS_ASSERT(u32Size >= 4);
1224 MS_ASSERT((MS_U32)pu8Data%2 == 0);
1225
1226 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
1227
1228 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(0x%08x,%p, %d)\n", __FUNCTION__, (unsigned int)u32Addr,pu8Data, (int)u32Size));
1229
1230 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
1231 {
1232 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_Read fails!\n"));
1233 return FALSE;
1234 }
1235
1236 u32Satrt = u32Addr;
1237 if(!_ParFlashInfo.bbytemode)
1238 u32Satrt >>= 1;
1239 for(u32ii = 0; u32ii < u32Size; u32ii++)
1240 {
1241 if(!HAL_PARFLASH_Read(u32Satrt, &u16temp))
1242 goto END;
1243 //printf("read dat (%d): %04x\n", (unsigned int)u32Satrt, u16temp);
1244 *pu8tr = (MS_U8)(u16temp & 0xFF);
1245 pu8tr++;
1246 if(!_ParFlashInfo.bbytemode)
1247 {
1248 *pu8tr = (MS_U8)((u16temp >> 8) & 0xFF);
1249 pu8tr++;
1250 u32ii++;
1251 }
1252 u32Satrt++;
1253 }
1254
1255 bRet = TRUE;
1256
1257 END:
1258 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
1259
1260 return bRet;
1261 }
1262
1263 //-------------------------------------------------------------------------------------------------
1264 /// Write write commend directly
1265 /// @param u8cycles \b IN: Bus cycles of commend. Maximun value is 8.
1266 /// @param pu32Addrs \b IN: Commend Address array to be written.
1267 /// @param pu16Data \b IN: Commend Data array to be written.
1268 /// @return TRUE : succeed
1269 /// @return FALSE : fail before timeout or illegal parameters
1270 /// @note Not allowed in interrupt context
1271 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_WriteCmdCycle(MS_U8 u8cycles,MS_U32 * pu32Addrs,MS_U16 * pu16Data)1272 MS_BOOL MDrv_PARFLASH_WriteCmdCycle(MS_U8 u8cycles, MS_U32 *pu32Addrs, MS_U16 *pu16Data)
1273 {
1274 MS_BOOL bRet = FALSE;
1275
1276 if(u8cycles > 8)
1277 return FALSE;
1278
1279 MS_ASSERT(MsOS_In_Interrupt() == FALSE);
1280
1281 DEBUG_PAR_FLASH(PARFLASH_DBGLV_DEBUG, printf("%s(%d, %p, %p)\n", __FUNCTION__, (int)u8cycles,pu32Addrs,pu16Data));
1282
1283 if (MsOS_ObtainMutex(_s32ParFlash_Mutex, PARFLASH_MUTEX_WAIT_TIME) == FALSE)
1284 {
1285 DEBUG_PAR_FLASH(PARFLASH_DBGLV_ERR, printf("ObtainMutex in MDrv_PARFLASH_Read fails!\n"));
1286 return FALSE;
1287 }
1288
1289 bRet = HAL_PARFLASH_Cmd_Write(u8cycles, pu32Addrs, pu16Data);
1290
1291 MsOS_ReleaseMutex(_s32ParFlash_Mutex);
1292
1293 return bRet;
1294 }
1295
1296 //-------------------------------------------------------------------------------------------------
1297 /// Getting Sector Offset address in byte unit
1298 /// @param u16sector \b IN: Sector index
1299 /// @return unsinged long value: Offset address
1300 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_GetSectorOffset(MS_U16 u16sector)1301 MS_U32 MDrv_PARFLASH_GetSectorOffset(MS_U16 u16sector)
1302 {
1303 MS_U32 u32offset;
1304
1305 u32offset = _Drv_PARFLASH_GetSectorOffset(u16sector);
1306
1307 if(!_ParFlashInfo.bbytemode)
1308 u32offset <<= 1;
1309
1310 return u32offset;
1311 }
1312
1313 //-------------------------------------------------------------------------------------------------
1314 /// Getting Sector size in byte unit
1315 /// @param u16startsec \b IN: Start Sector index
1316 /// @param u16endsec \b IN: End Sector index
1317 /// @return unsinged long value: sector size
1318 //-------------------------------------------------------------------------------------------------
MDrv_PARFLASH_GetSectorSize(MS_U16 u16startsec,MS_U16 u16endsec)1319 MS_U32 MDrv_PARFLASH_GetSectorSize(MS_U16 u16startsec, MS_U16 u16endsec)
1320 {
1321 MS_U32 u32size = 0;
1322 MS_U16 u16ii;
1323
1324 for(u16ii = u16startsec; u16ii <= u16endsec; u16ii++)
1325 u32size += _Drv_PARFLASH_GetSectorSize(u16ii);
1326
1327 if(!_ParFlashInfo.bbytemode)
1328 u32size <<= 1;
1329
1330 return u32size;
1331 }
1332
1333