1 /******************************************************************************
2 ******************************************************************************
3 *
4 * @file flash.c
5 *
6 * @brief application entry point which performs application specific tasks.
7 *
8 *******************************************************************************
9 *
10 * provide a demo for how to initialize the NV32, output messages via SCI,
11 * flash operations, etc.
12 * NOTE:
13 *	printf call may occupy a lot of memory (around 1924 bytes), so please
14 *	consider your code size before using printf.
15 ******************************************************************************
16 *
17 * provide FLASH driver
18 *
19 ******************************************************************************/
20 
21 #include "flash.h"
22 /******************************************************************************
23 * Global variables
24 ******************************************************************************/
25 
26 /******************************************************************************
27 * Constants and macros
28 ******************************************************************************/
29 
30 
31 /******************************************************************************
32 * Local types
33 ******************************************************************************/
34 
35 /******************************************************************************
36 * Local function prototypes
37 ******************************************************************************/
38 
39 /******************************************************************************
40 * Local variables
41 ******************************************************************************/
42 
43 /******************************************************************************
44 * Local functions
45 ******************************************************************************/
46 
47 /******************************************************************************
48 * Global functions
49 ******************************************************************************/
50 /*****************************************************************************//*!
51 +FUNCTION----------------------------------------------------------------
52 * @function name: Flash_CopyInRAM
53 *
54 * @brief This section of the code is the one that copies the routine into RAM.
55 * It is following the steps  documented in Technical Note 228
56 *
57 * @param
58 *
59 * @return none
60 *
61 * @ Pass/ Fail criteria: none
62 *****************************************************************************/
63 
64 #define FLASH_ENABLE_STALLING_FLASH_CONTROLLER
65 
66 
67 /*****************************************************************************//*!
68 +FUNCTION----------------------------------------------------------------
69 * @function name: Flash_Init
70 *
71 * @brief initialize flash driver
72 *
73 * @param
74 *
75 * @return none
76 *
77 * @ Pass/ Fail criteria: none
78 *****************************************************************************/
79 
Flash_Init(void)80 uint16_t Flash_Init(void)
81 {
82 	uint16_t err   = FLASH_ERR_SUCCESS;
83 	uint32_t clkDIV = BUS_CLK_HZ/1000000L - 1;
84 	uint32_t Tpgs  =(285 *(BUS_CLK_HZ/100))/1000000L;  //update 2016.8.4 by ��Ű��GG
85 	uint32_t Tprog =(675*(BUS_CLK_HZ/100))/1000000L;   //by ��Ű��GG
86 //        printf("Tpgs= %x \n" , Tpgs);
87 //        printf("Tprog= %x \n" , Tprog);
88 
89 	EFMCR=(clkDIV<<24) + 0x00001103; //divide to 1M hz
90 	EFMETM0=(Tpgs<<16)  + 0x00001194;  //0x00281194; //
91 	EFMETM1=(Tprog<<16) + 0x000088B8; //
92 //        printf("EFMCR= %x \n" , EFMCR);
93 //        printf("EFMETM0= %x \n" , EFMETM0);
94 //        printf("EFMETM1= %x \n" , EFMETM1);
95   return(err);
96 }
97 
98 /*****************************************************************************//*!
99 +FUNCTION----------------------------------------------------------------
100 * @function name: FlashProgram
101 *
102 * @brief program flash routine, each program operation supports up to 2 longwords
103 * 		 programming
104 *
105 * @param
106 *
107 * @return none
108 *
109 * @ Pass/ Fail criteria: none
110 *****************************************************************************/
111 
Flash_Program(uint32_t wNVMTargetAddress,uint8_t * pData,uint16_t sizeBytes)112 uint16_t Flash_Program(uint32_t wNVMTargetAddress, uint8_t *pData, uint16_t sizeBytes)
113 {
114 	uint16_t err = FLASH_ERR_SUCCESS;
115 	uint16_t w2LongWordCount = sizeBytes>>3;
116 	uint8_t  wLeftBytes = (sizeBytes & 0x07);
117 	uint16_t wLeftLongWords = wLeftBytes>>2;
118 	uint32_t wTargetAddress = wNVMTargetAddress;
119 	uint32_t dwData0,dwData1;
120 	uint32_t *pdwData = (uint32_t*)pData;
121 	int  i;
122  //printf("\n adr : 0x%x ,data = 0x%x\n",w2LongWordCount,wLeftLongWords );
123 	// Check address to see if it is aligned to 4 bytes
124 	// Global address [1:0] must be 00.
125 	if(wNVMTargetAddress & 0x03)
126 	{
127 		err = FLASH_ERR_INVALID_PARAM;
128 		return (err);
129 	}
130 	// Loop for the two longwords (8 bytes) programming
131 	for(i = 0; i < w2LongWordCount; i++)
132 	{
133 		dwData0 = *pdwData++;
134 		dwData1 = *pdwData++;
135 		err = Flash_Program2LongWords(wTargetAddress, dwData0, dwData1);
136 		if(err)
137 		{
138 			goto EndP;
139 			//break;
140 		}
141 		wTargetAddress += 8;
142 	}
143 	// Loop for the single longword (4 bytes) programming
144 	for(i = 0; i < wLeftLongWords; i++)
145 	{
146 		dwData0 = *pdwData++;
147 		//printf("\n adr : 0x%x ,data = 0x%x\n",i,dwData0 );
148 		err = Flash_Program1LongWord(wTargetAddress, dwData0);
149     //printf("\n adr : 0x%x ,data = 0x%x\n",i,dwData0 );
150 		if(err)
151 		{
152 			goto EndP;
153 			//break;
154 		}
155 		wTargetAddress += 4;
156 	}
157 	wLeftBytes = (wLeftBytes-(wLeftLongWords<<2));	// calculate the # of bytes that are not programmed
158 	if(!wLeftBytes){
159 		return (err);
160 	}
161 
162 #if     defined(BIG_ENDIAN)
163 	dwData0 = 0;
164 	pData = (uint8_t*)pdwData;	// pointer to the left bytes
165 	for(i = wLeftBytes; i >0; i--)
166 	{
167 		dwData0 <<= 8;
168 		dwData0 |= *pData++;	// MSB byte first
169 	}
170 	// Calculate how many bytes need to be filled with 0xFFs
171 	// in order to form a single longword for the left bytes of data
172 	wLeftBytes = 4 - wLeftBytes;
173 	//
174 	for(i = wLeftBytes; i >0; i--)
175 	{
176 		dwData0 <<= 8;
177 		dwData0 |= 0xFF;	// MSB byte first
178 	}
179 #else
180 	dwData0 = 0xFFFFFFFFL;
181 	pData = (uint8_t*)pdwData+wLeftBytes-1;	// pointer to the left bytes
182 	for(i = wLeftBytes; i >0; i--)
183 	{
184 		dwData0 <<= 8;
185 		dwData0 |= *pData--;	// MSB byte first
186 	}
187 #endif
188 	// Now program the last longword
189 	err = Flash_Program1LongWord(wTargetAddress, dwData0);
190 EndP:
191 	return (err);
192 }
193 
Flash_Program1LongWord(uint32_t wNVMTargetAddress,uint32_t dwData)194 uint16_t Flash_Program1LongWord(uint32_t wNVMTargetAddress, uint32_t dwData)
195 {
196 	uint16_t err = FLASH_ERR_SUCCESS;
197 
198 	// Check address to see if it is aligned to 4 bytes
199 	// Global address [1:0] must be 00.
200 	if(wNVMTargetAddress & 0x03)
201 	{
202 		err = FLASH_ERR_INVALID_PARAM;
203 		return (err);
204 	}
205 	// Clear error flags
206 	EFMCMD = FLASH_CMD_CLEAR;
207 	// Write index to specify the command code to be loaded
208 	M32(wNVMTargetAddress) = dwData;
209 	// Write command code and memory address bits[23:16]
210         EFM_LaunchCMD(FLASH_CMD_PROGRAM);
211 	return (err);
212 }
213 
214 
Flash_Program2LongWords(uint32_t wNVMTargetAddress,uint32_t dwData0,uint32_t dwData1)215 uint16_t Flash_Program2LongWords(uint32_t wNVMTargetAddress, uint32_t dwData0, uint32_t dwData1)
216 {
217 	uint16_t err = FLASH_ERR_SUCCESS;
218 
219 
220 	// Check address to see if it is aligned to 4 bytes
221 	// Global address [1:0] must be 00.
222 	if(wNVMTargetAddress & 0x03)
223 	{
224 		err = FLASH_ERR_INVALID_PARAM;
225 		return (err);
226 	}
227 	// Clear error flags
228 
229 	EFMCMD = FLASH_CMD_CLEAR;
230 
231 //	printf("\n write data  adr : 0x%x ,data = 0x%x\n",dwData0,dwData1 );
232 	// Write index to specify the command code to be loaded
233 	M32(wNVMTargetAddress) = dwData0;
234 	// Write command code and memory address bits[23:16]
235   EFM_LaunchCMD(FLASH_CMD_PROGRAM);
236 	wNVMTargetAddress = wNVMTargetAddress +4;
237 
238 	//	printf("\n write data  adr : 0x%x ,data = 0x%x\n",wNVMTargetAddress,dwData1 );
239 	// Clear error flags
240 		EFMCMD = FLASH_CMD_CLEAR;
241 	// Write index to specify the command code to be loaded
242 	M32(wNVMTargetAddress) = dwData1;
243 	// Write command code and memory address bits[23:16]
244   EFM_LaunchCMD(FLASH_CMD_PROGRAM);
245 //	printf("\n write data  adr : 0x%x ,data = 0x%x\n",wNVMTargetAddress,dwData1 );
246 	return (err);
247 }
248 
249 
250 
251 
252 
253 /*****************************************************************************//*!
254 +FUNCTION----------------------------------------------------------------
255 * @function name: Flash_EraseSector
256 *
257 * @brief erase flash sector, each flash sector is of 512 bytes long,
258 * global address [1:0] = 00.
259 *
260 * @param
261 *
262 * @return none
263 *
264 * @ Pass/ Fail criteria: none
265 *****************************************************************************/
Flash_EraseSector(uint32_t wNVMTargetAddress)266 uint16_t  Flash_EraseSector(uint32_t wNVMTargetAddress)
267 {
268 	uint16_t err = FLASH_ERR_SUCCESS;
269 	// Check address to see if it is aligned to 4 bytes
270 	// Global address [1:0] must be 00.
271 	if(wNVMTargetAddress & 0x03)
272 	{
273 		err = FLASH_ERR_INVALID_PARAM;
274 		return (err);
275 	}
276 	// Clear error flags
277 		EFMCMD = FLASH_CMD_CLEAR;
278 	  M32(wNVMTargetAddress) = 0xffffffff;
279 	  EFM_LaunchCMD(FLASH_CMD_ERASE_SECTOR);
280 	return (err);
281 }
282 
Flash_VerifyBackdoorKey()283 uint16_t Flash_VerifyBackdoorKey()
284 {
285 	uint16_t err = FLASH_ERR_SUCCESS;
286 //        int i;
287 
288 	// Clear error flags
289 		EFMCMD = FLASH_CMD_CLEAR;
290 	// Write index to specify the command code to be loaded
291 	 Custombkd = FLASH_FACTORY_KEY;
292 	return (err);
293 }
294 
295 /*****************************************************************************//*!
296 +FUNCTION----------------------------------------------------------------
297 * @function name: NVM_EraseAll
298 *
299 * @brief erase all block,both flash and EEPROM
300 *
301 * @param
302 *
303 * @return none
304 *
305 * @ Pass/ Fail criteria: none
306 *****************************************************************************/
NVM_EraseAll(void)307 uint16_t NVM_EraseAll(void)
308 {
309 	uint16_t err = FLASH_ERR_SUCCESS;
310 		EFMCMD = FLASH_CMD_CLEAR;
311 	  EFM_LaunchCMD(FLASH_CMD_ERASE_ALL);
312 	// Clear error flags
313     return err;
314 }
315 
316 /*****************************************************************************//*!
317 +FUNCTION----------------------------------------------------------------
318 * @function name: NVM_Unsecure
319 *
320 * @brief unsecure
321 *
322 * @param
323 *
324 * @return none
325 *
326 * @ Pass/ Fail criteria: none
327 *****************************************************************************/
NVM_Unsecure(void)328 uint16_t NVM_Unsecure(void)
329 {
330 	uint16_t err = FLASH_ERR_SUCCESS;
331 
332     return err;
333 }
334 
335 #ifdef IAR
EFM_LaunchCMD(uint32_t EFM_CMD)336 void __ramfunc EFM_LaunchCMD(uint32_t EFM_CMD)
337 #else
338 void EFM_LaunchCMD(uint32_t EFM_CMD)
339 #endif
340 {
341   DisableInterrupts;
342 		if((EFMCMD&EFM_DONE_MASK)== EFM_STATUS_READY)
343 		{
344 	  EFMCMD = EFM_CMD;
345 		}
346 	while(1)
347 	{
348 		if((EFMCMD&EFM_DONE_MASK) == EFM_STATUS_DONE) break;
349 	}
350  EnableInterrupts;
351 }
352