init
[pyfrprog.git] / Flash.c
1 /*****************************************************************************/\r
2 /* THIS SAMPLE CODE IS PROVIDED AS IS AND IS SUBJECT TO ALTERATIONS. FUJITSU */\r
3 /* MICROELECTRONICS ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR */\r
4 /* ELIGIBILITY FOR ANY PURPOSES.                                             */\r
5 /*                 (C) Fujitsu Microelectronics Europe GmbH                  */\r
6 /*****************************************************************************/\r
7 \r
8 #include "Flash.h"\r
9 #include "mb91465k.h"\r
10 \r
11 static unsigned int IFlag;\r
12 \r
13 #pragma section CODE=IRAM,attr=CODE\r
14         \r
15 \r
16 void FLASH_PrepareWriteHalfWordMode()\r
17 {\r
18         /*      Set FLASH Access Mode via BootROM Routine       */\r
19         /*      For details refer to the Hardware Manual or Data Sheet */\r
20 #pragma asm\r
21         ST              RP,@-R15\r
22         STM0    (R4,R5)\r
23         STM1    (R12)\r
24         LDI             #0x01,R4        ; Set FLASH to 16Bit read/write Mode\r
25         LDI             #0x04,R5        ; Go 4 times through delay loop (64MHz CLKB)\r
26         LDI             #0xBF60,R12\r
27         CALL    @R12\r
28         LDM1    (R12)\r
29         LDM0    (R4,R5)\r
30         LD              @R15+,RP\r
31 #pragma endasm\r
32         \r
33         /*      Set the FLASH Interface to Write Timing */\r
34         /*      For details refer to the Hardware Manual or Data Sheet */\r
35         /*      Setting shown here is for CLKB = 64MHz  */\r
36         FMWT_ATD = 1;\r
37         FMWT_WEXH = 0;\r
38         FMWT_WTC = 8;\r
39 }\r
40 \r
41 void FLASH_PrepareReadMode()\r
42 {\r
43         /*      Set FLASH Access Mode via BootROM Routine       */\r
44         /*      For details refer to the Hardware Manual or Data Sheet */\r
45 #pragma asm\r
46         ST              RP,@-R15\r
47         STM0    (R4,R5)\r
48         STM1    (R12)\r
49         LDI             #0x00,R4        ; Set FLASH to 32Bit read/write Mode\r
50         LDI             #0x04,R5        ; Go 4 times through delay loop (64MHz CLKB)\r
51         LDI             #0xBF60,R12\r
52         CALL    @R12\r
53         LDM1    (R12)\r
54         LDM0    (R4,R5)\r
55         LD              @R15+,RP\r
56 #pragma endasm\r
57         \r
58         /*      Set the FLASH Interface to Read Timing  */\r
59         /*      For details refer to the Hardware Manual or Data Sheet */\r
60         /*      Setting shown here is for CLKB = 64MHz  */\r
61         FMWT_ATD = 1;\r
62         FMWT_EQ = 3;\r
63         FMWT_WTC = 4;\r
64 }               \r
65                 \r
66         \r
67 unsigned char FLASH_SectorErase(unsigned int secadr)\r
68 {\r
69         unsigned char flag = 0;\r
70         volatile unsigned int value = 0;\r
71         \r
72         /*      Disable Interrupts if necessary */\r
73         IFlag = FLASH_SaveDisableInterruptFlag();\r
74 \r
75         /*      Set FLASH access mode to 16Bit Write Mode       */\r
76         FLASH_PrepareWriteHalfWordMode();\r
77                                         \r
78         secadr |= 0x0003;\r
79         \r
80         /*      Start FLASH Sector Erase Sequence       */\r
81         *hseq_1 = 0x00AA;\r
82         *hseq_2 = 0x0055;\r
83         *hseq_1 = 0x0080;\r
84         *hseq_1 = 0x00AA;\r
85         *hseq_2 = 0x0055;\r
86         *(unsigned  short int *)secadr = 0x0030;\r
87 \r
88         /*      Wait for the Auto Algorithm to start    */\r
89         while( !( *(unsigned  short int *)secadr & SETIMR ) )\r
90         {\r
91                 /*      Feed the Hardware Watchdog      */\r
92                 HWWD_CL = 0;\r
93                 \r
94                 /*      Check for Pending Interrupts    */\r
95                 if( FLASH_CheckPendingInterrupt() )\r
96                 {               \r
97                         /*      Wait for Sector Erase Suspend   */\r
98                         FLASH_SuspendSectorErase(secadr);\r
99                         \r
100                 /*      Set FLASH access mode to 32Bit Read Mode        */\r
101                 FLASH_PrepareReadMode();\r
102                         \r
103                         /*      Restore the original Interrupt Flag     */\r
104                         FLASH_RestoreInterruptFlag(IFlag);\r
105                                                 \r
106                         /*      Keep on checking for pending Interrupts */\r
107                         while( FLASH_CheckPendingInterrupt() ) HWWD_CL = 0;\r
108                         \r
109                         /*      Disable Interrupts if necessary */\r
110                         IFlag = FLASH_SaveDisableInterruptFlag();\r
111                         \r
112                         /*      Set FLASH access mode to 16Bit Write Mode       */\r
113                 FLASH_PrepareWriteHalfWordMode();\r
114                                                 \r
115                         /*      Sector Erase Resume     */\r
116                         FLASH_ResumeSectorErase(secadr);\r
117                 }               \r
118         }\r
119 \r
120         /*      Wait for the Auto Algorithm to finish   */\r
121         while( flag == 0 )\r
122         {\r
123                 /* Feed Hardware Watchdog */\r
124                 HWWD_CL = 0;\r
125 \r
126                 /*      Check for Pending Interrupts    */\r
127                 if( FLASH_CheckPendingInterrupt() )\r
128                 {               \r
129                         /*      Sector Erase Suspend    */\r
130                         FLASH_SuspendSectorErase(secadr);\r
131                         \r
132                 /*      Set FLASH access mode to 32Bit Read Mode        */\r
133                 FLASH_PrepareReadMode();\r
134                                         \r
135                         /*      Restore the original Interrupt Flag     */\r
136                         FLASH_RestoreInterruptFlag(IFlag);\r
137                                                                         \r
138                         /*      Keep on checking for pending Interrupts */\r
139                         while( FLASH_CheckPendingInterrupt() ) HWWD_CL = 0;\r
140 \r
141                         /*      Disable Interrupts if necessary */\r
142                         IFlag = FLASH_SaveDisableInterruptFlag();\r
143                         \r
144                         /*      Set FLASH access mode to 16Bit Write Mode       */\r
145                 FLASH_PrepareWriteHalfWordMode();\r
146                                                 \r
147                         /*      Sector Erase Resume     */\r
148                         FLASH_ResumeSectorErase(secadr);\r
149                 }               \r
150                 \r
151                         \r
152                 /*      Check the Hardware Sequence Flags       */                              \r
153                 if( ( *(unsigned short int *)secadr /* value */ & DPOLL ) )\r
154                 {\r
155                         flag = 1;\r
156                 }\r
157                 if( ( *(unsigned short int *)secadr /* value */ & TLOVER ) )\r
158                 {\r
159                         if( ( *(unsigned short int *)secadr /* value */ & DPOLL ) )\r
160                         {\r
161                                 flag = 1;\r
162                         }\r
163                         else\r
164                         {\r
165                                 /*      Reset FLASH     */\r
166                                 FLASH_ReadReset();\r
167                                 \r
168                                 flag = 2;\r
169                         }\r
170                 }\r
171         }\r
172         \r
173 \r
174         /*      Restore the original Interrupt Flag     */\r
175         FLASH_RestoreInterruptFlag(IFlag);\r
176         \r
177         /*      Set FLASH access mode to 32Bit Read Mode        */\r
178         FLASH_PrepareReadMode();\r
179                 \r
180         return flag;\r
181 }\r
182 \r
183 unsigned char FLASH_SectorBlankCheck(unsigned int secaddr, unsigned int size)\r
184 {\r
185         unsigned int count;\r
186         unsigned char empty_flag = 0;\r
187         unsigned int addr = secaddr;\r
188                 \r
189         /*      Clear FIXE bit to see FLASH memory content instead of fixed reset vector        */\r
190         FMCS_FIXE = 0;\r
191         \r
192         for(count = 0; count < size; count ++)\r
193         {\r
194                 /*      Clear Hardware Watchdog */\r
195                 HWWD_CL = 0;\r
196                 if( *(unsigned int *)addr != 0xFFFFFFFF ) empty_flag = 1;\r
197                 addr += 4;\r
198         }\r
199         \r
200         /*      Set FIXE bit to see fixed reset vector  */\r
201         FMCS_FIXE = 1;\r
202 \r
203         if( empty_flag != 0 )\r
204         {\r
205                 return 2;\r
206         }\r
207         \r
208         return 1;\r
209 }\r
210 \r
211 unsigned char FLASH_WriteHalfWord(unsigned int adr, unsigned short int data)\r
212 {\r
213         unsigned char flag = 0;\r
214 \r
215         /*      Disable Interrupts if necessary */\r
216         IFlag = FLASH_SaveDisableInterruptFlag();\r
217                         \r
218         /*      Set FLASH access mode to 16Bit Write Mode       */\r
219         FLASH_PrepareWriteHalfWordMode();\r
220         \r
221         /*      Start Write FLASH Sequence      */\r
222         *hseq_1 = 0x00AA;\r
223         *hseq_2 = 0x0055;\r
224         *hseq_1 = 0x00A0;\r
225         *((volatile unsigned short int *)adr) = data;\r
226         \r
227         /*      Wait for the Auto Algorithm to finish   */\r
228         while( flag == 0 )\r
229         {\r
230                 /* Feed Hardware Watchdog */\r
231                 HWWD_CL = 0;\r
232                 \r
233                 if( ( *(volatile unsigned short int *)adr & DPOLL ) == (data & DPOLL) )\r
234                 {\r
235                         flag = 1;\r
236                 }\r
237                 if( ( *(volatile unsigned short int *)adr & TLOVER ) == TLOVER )\r
238                 {\r
239                         if( ( *(volatile unsigned short int *)adr & DPOLL ) == (data & DPOLL) )\r
240                         {\r
241                                 flag = 1;\r
242                         }\r
243                         else\r
244                         {\r
245                                 /*      Reset FLASH (keep in mind 16Bit access to FLASH)        */\r
246                                 *hseq_1 = 0x00F0;       // Keep in Mind (16Bit access)\r
247                                 \r
248                                 flag = 2;\r
249                         }\r
250                 }\r
251         }\r
252 \r
253         /*      Set FLASH access mode to 32Bit Read Mode        */\r
254         FLASH_PrepareReadMode();\r
255         \r
256         /*      Restore the original Interrupt Flag     */\r
257         FLASH_RestoreInterruptFlag(IFlag);\r
258         \r
259         return flag;\r
260 }\r
261 \r
262 \r
263 unsigned char FLASH_ReadReset()\r
264 {\r
265         *hseq_1 = 0x00F0;\r
266         \r
267         return 1;\r
268 }\r
269 \r
270 #pragma asm\r
271 _FLASH_SaveDisableInterruptFlag:\r
272         STM0 (R0)\r
273         MOV PS,R4\r
274         LDI     #0x00000010,R0  \r
275         AND R0,R4                       ; Store Original Flag\r
276         ANDCCR #0xFFFFFFEF      ; Clear Interrupt Flag\r
277         LDM0 (R0)       \r
278         RET\r
279 #pragma endasm\r
280 \r
281 \r
282 #pragma asm\r
283 _FLASH_RestoreInterruptFlag:\r
284         STM0 (R0)\r
285         MOV PS,R0                       ; Get current PS\r
286         OR R4,R0                        ; Set Flag as saved\r
287         MOV R0,PS                       ; Write back PS\r
288         LDM0 (R0)\r
289         RET\r
290 #pragma endasm\r
291 \r
292 \r
293 unsigned char FLASH_SuspendSectorErase(unsigned int secaddr)\r
294 {               \r
295         /* Write Sector Erase Suspend Command   */\r
296         *(volatile unsigned short int *)secaddr = 0x00B0;\r
297 \r
298         /*      Wait for the FLASH macro to suspend sector erase        */              \r
299         while(!(*(unsigned short int *)secaddr /* value */ & DPOLL) && (*(unsigned short int *)secaddr /* value */ & SETIMR))\r
300         {\r
301                 HWWD_CL=0;\r
302         }\r
303         \r
304         return 1;\r
305 }\r
306 \r
307 unsigned char FLASH_ResumeSectorErase(unsigned int secaddr)\r
308 {\r
309         /*      Write the Sector Erase Resume Command   */\r
310         *(volatile unsigned short int *)secaddr = 0x0030;\r
311         \r
312         /*      Wait for the FLASH Macro to resume sector erase */              \r
313         while((*(unsigned short int *)secaddr /*value */ & DPOLL) && !(*(unsigned short int *)secaddr /*value */ & SETIMR))\r
314         {\r
315                 HWWD_CL=0;\r
316         }\r
317         \r
318         return 1;               \r
319 }\r
320 \r
321 unsigned char FLASH_CheckPendingInterrupt()\r
322 {\r
323         /*      Poll for Pending Interrupts which are needed here       */\r
324         if(TMCSR0_UF) return 1; /* in this sample the only interrupt source supervised is Reload Timer 0        */\r
325         \r
326         /*      and return 1 when an Interrupt is pending       */\r
327         return 0;\r
328 }\r