xref: /utopia/UTPA2-700.0.x/modules/flash/drv/flash/nor/drvPARFLASH.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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