1 |
581 |
jeremybenn |
//*****************************************************************************
|
2 |
|
|
//
|
3 |
|
|
// flash.c - Driver for programming the on-chip flash.
|
4 |
|
|
//
|
5 |
|
|
// Copyright (c) 2005,2006 Luminary Micro, Inc. All rights reserved.
|
6 |
|
|
//
|
7 |
|
|
// Software License Agreement
|
8 |
|
|
//
|
9 |
|
|
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
|
10 |
|
|
// exclusively on LMI's Stellaris Family of microcontroller products.
|
11 |
|
|
//
|
12 |
|
|
// The software is owned by LMI and/or its suppliers, and is protected under
|
13 |
|
|
// applicable copyright laws. All rights are reserved. Any use in violation
|
14 |
|
|
// of the foregoing restrictions may subject the user to criminal sanctions
|
15 |
|
|
// under applicable laws, as well as to civil liability for the breach of the
|
16 |
|
|
// terms and conditions of this license.
|
17 |
|
|
//
|
18 |
|
|
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
19 |
|
|
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
20 |
|
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
21 |
|
|
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
22 |
|
|
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
23 |
|
|
//
|
24 |
|
|
// This is part of revision 991 of the Stellaris Driver Library.
|
25 |
|
|
//
|
26 |
|
|
//*****************************************************************************
|
27 |
|
|
|
28 |
|
|
//*****************************************************************************
|
29 |
|
|
//
|
30 |
|
|
//! \addtogroup flash_api
|
31 |
|
|
//! @{
|
32 |
|
|
//
|
33 |
|
|
//*****************************************************************************
|
34 |
|
|
|
35 |
|
|
#include "../hw_flash.h"
|
36 |
|
|
#include "../hw_ints.h"
|
37 |
|
|
#include "../hw_memmap.h"
|
38 |
|
|
#include "../hw_sysctl.h"
|
39 |
|
|
#include "../hw_types.h"
|
40 |
|
|
#include "debug.h"
|
41 |
|
|
#include "flash.h"
|
42 |
|
|
#include "interrupt.h"
|
43 |
|
|
|
44 |
|
|
//*****************************************************************************
|
45 |
|
|
//
|
46 |
|
|
//! Gets the number of processor clocks per micro-second.
|
47 |
|
|
//!
|
48 |
|
|
//! This function returns the number of clocks per micro-second, as presently
|
49 |
|
|
//! known by the flash controller.
|
50 |
|
|
//!
|
51 |
|
|
//! \return Returns the number of processor clocks per micro-second.
|
52 |
|
|
//
|
53 |
|
|
//*****************************************************************************
|
54 |
|
|
#if defined(GROUP_usecget) || defined(BUILD_ALL) || defined(DOXYGEN)
|
55 |
|
|
unsigned long
|
56 |
|
|
FlashUsecGet(void)
|
57 |
|
|
{
|
58 |
|
|
//
|
59 |
|
|
// Return the number of clocks per micro-second.
|
60 |
|
|
//
|
61 |
|
|
return(HWREG(FLASH_USECRL) + 1);
|
62 |
|
|
}
|
63 |
|
|
#endif
|
64 |
|
|
|
65 |
|
|
//*****************************************************************************
|
66 |
|
|
//
|
67 |
|
|
//! Sets the number of processor clocks per micro-second.
|
68 |
|
|
//!
|
69 |
|
|
//! \param ulClocks is the number of processor clocks per micro-second.
|
70 |
|
|
//!
|
71 |
|
|
//! This function is used to tell the flash controller the number of processor
|
72 |
|
|
//! clocks per micro-second. This value must be programmed correctly or the
|
73 |
|
|
//! flash most likely will not program correctly; it has no affect on reading
|
74 |
|
|
//! flash.
|
75 |
|
|
//!
|
76 |
|
|
//! \return None.
|
77 |
|
|
//
|
78 |
|
|
//*****************************************************************************
|
79 |
|
|
#if defined(GROUP_usecset) || defined(BUILD_ALL) || defined(DOXYGEN)
|
80 |
|
|
void
|
81 |
|
|
FlashUsecSet(unsigned long ulClocks)
|
82 |
|
|
{
|
83 |
|
|
//
|
84 |
|
|
// Set the number of clocks per micro-second.
|
85 |
|
|
//
|
86 |
|
|
HWREG(FLASH_USECRL) = ulClocks - 1;
|
87 |
|
|
}
|
88 |
|
|
#endif
|
89 |
|
|
|
90 |
|
|
//*****************************************************************************
|
91 |
|
|
//
|
92 |
|
|
//! Erases a block of flash.
|
93 |
|
|
//!
|
94 |
|
|
//! \param ulAddress is the start address of the flash block to be erased.
|
95 |
|
|
//!
|
96 |
|
|
//! This function will erase a 1 kB block of the on-chip flash. After erasing,
|
97 |
|
|
//! the block will be filled with 0xFF bytes. Read-only and execute-only
|
98 |
|
|
//! blocks cannot be erased.
|
99 |
|
|
//!
|
100 |
|
|
//! This function will not return until the block has been erased.
|
101 |
|
|
//!
|
102 |
|
|
//! \return Returns 0 on success, or -1 if an invalid block address was
|
103 |
|
|
//! specified or the block is write-protected.
|
104 |
|
|
//
|
105 |
|
|
//*****************************************************************************
|
106 |
|
|
#if defined(GROUP_erase) || defined(BUILD_ALL) || defined(DOXYGEN)
|
107 |
|
|
long
|
108 |
|
|
FlashErase(unsigned long ulAddress)
|
109 |
|
|
{
|
110 |
|
|
//
|
111 |
|
|
// Check the arguments.
|
112 |
|
|
//
|
113 |
|
|
ASSERT(!(ulAddress & (FLASH_ERASE_SIZE - 1)));
|
114 |
|
|
|
115 |
|
|
//
|
116 |
|
|
// Clear the flash access interrupt.
|
117 |
|
|
//
|
118 |
|
|
HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
|
119 |
|
|
|
120 |
|
|
//
|
121 |
|
|
// Erase the block.
|
122 |
|
|
//
|
123 |
|
|
HWREG(FLASH_FMA) = ulAddress;
|
124 |
|
|
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
|
125 |
|
|
|
126 |
|
|
//
|
127 |
|
|
// Wait until the word has been programmed.
|
128 |
|
|
//
|
129 |
|
|
while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
|
130 |
|
|
{
|
131 |
|
|
}
|
132 |
|
|
|
133 |
|
|
//
|
134 |
|
|
// Return an error if an access violation occurred.
|
135 |
|
|
//
|
136 |
|
|
if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
|
137 |
|
|
{
|
138 |
|
|
return(-1);
|
139 |
|
|
}
|
140 |
|
|
|
141 |
|
|
//
|
142 |
|
|
// Success.
|
143 |
|
|
//
|
144 |
|
|
return(0);
|
145 |
|
|
}
|
146 |
|
|
#endif
|
147 |
|
|
|
148 |
|
|
//*****************************************************************************
|
149 |
|
|
//
|
150 |
|
|
//! Programs flash.
|
151 |
|
|
//!
|
152 |
|
|
//! \param pulData is a pointer to the data to be programmed.
|
153 |
|
|
//! \param ulAddress is the starting address in flash to be programmed. Must
|
154 |
|
|
//! be a multiple of four.
|
155 |
|
|
//! \param ulCount is the number of bytes to be programmed. Must be a multiple
|
156 |
|
|
//! of four.
|
157 |
|
|
//!
|
158 |
|
|
//! This function will program a sequence of words into the on-chip flash.
|
159 |
|
|
//! Programming each location consists of the result of an AND operation
|
160 |
|
|
//! of the new data and the existing data; in other words bits that contain
|
161 |
|
|
//! 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed
|
162 |
|
|
//! to 1. Therefore, a word can be programmed multiple times as long as these
|
163 |
|
|
//! rules are followed; if a program operation attempts to change a 0 bit to
|
164 |
|
|
//! a 1 bit, that bit will not have its value changed.
|
165 |
|
|
//!
|
166 |
|
|
//! Since the flash is programmed one word at a time, the starting address and
|
167 |
|
|
//! byte count must both be multiples of four. It is up to the caller to
|
168 |
|
|
//! verify the programmed contents, if such verification is required.
|
169 |
|
|
//!
|
170 |
|
|
//! This function will not return until the data has been programmed.
|
171 |
|
|
//!
|
172 |
|
|
//! \return Returns 0 on success, or -1 if a programming error is encountered.
|
173 |
|
|
//
|
174 |
|
|
//*****************************************************************************
|
175 |
|
|
#if defined(GROUP_program) || defined(BUILD_ALL) || defined(DOXYGEN)
|
176 |
|
|
long
|
177 |
|
|
FlashProgram(unsigned long *pulData, unsigned long ulAddress,
|
178 |
|
|
unsigned long ulCount)
|
179 |
|
|
{
|
180 |
|
|
//
|
181 |
|
|
// Check the arguments.
|
182 |
|
|
//
|
183 |
|
|
ASSERT(!(ulAddress & 3));
|
184 |
|
|
ASSERT(!(ulCount & 3));
|
185 |
|
|
|
186 |
|
|
//
|
187 |
|
|
// Clear the flash access interrupt.
|
188 |
|
|
//
|
189 |
|
|
HWREG(FLASH_FCMISC) = FLASH_FCMISC_ACCESS;
|
190 |
|
|
|
191 |
|
|
//
|
192 |
|
|
// Loop over the words to be programmed.
|
193 |
|
|
//
|
194 |
|
|
while(ulCount)
|
195 |
|
|
{
|
196 |
|
|
//
|
197 |
|
|
// Program the next word.
|
198 |
|
|
//
|
199 |
|
|
HWREG(FLASH_FMA) = ulAddress;
|
200 |
|
|
HWREG(FLASH_FMD) = *pulData;
|
201 |
|
|
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
|
202 |
|
|
|
203 |
|
|
//
|
204 |
|
|
// Wait until the word has been programmed.
|
205 |
|
|
//
|
206 |
|
|
while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
|
207 |
|
|
{
|
208 |
|
|
}
|
209 |
|
|
|
210 |
|
|
//
|
211 |
|
|
// Increment to the next word.
|
212 |
|
|
//
|
213 |
|
|
pulData++;
|
214 |
|
|
ulAddress += 4;
|
215 |
|
|
ulCount -= 4;
|
216 |
|
|
}
|
217 |
|
|
|
218 |
|
|
//
|
219 |
|
|
// Return an error if an access violation occurred.
|
220 |
|
|
//
|
221 |
|
|
if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ACCESS)
|
222 |
|
|
{
|
223 |
|
|
return(-1);
|
224 |
|
|
}
|
225 |
|
|
|
226 |
|
|
//
|
227 |
|
|
// Success.
|
228 |
|
|
//
|
229 |
|
|
return(0);
|
230 |
|
|
}
|
231 |
|
|
#endif
|
232 |
|
|
|
233 |
|
|
//*****************************************************************************
|
234 |
|
|
//
|
235 |
|
|
//! Gets the protection setting for a block of flash.
|
236 |
|
|
//!
|
237 |
|
|
//! \param ulAddress is the start address of the flash block to be queried.
|
238 |
|
|
//!
|
239 |
|
|
//! This function will get the current protection for the specified 2 kB block
|
240 |
|
|
//! of flash. Each block can be read/write, read-only, or execute-only.
|
241 |
|
|
//! Read/write blocks can be read, executed, erased, and programmed. Read-only
|
242 |
|
|
//! blocks can be read and executed. Execute-only blocks can only be executed;
|
243 |
|
|
//! processor and debugger data reads are not allowed.
|
244 |
|
|
//!
|
245 |
|
|
//! \return Returns the protection setting for this block. See
|
246 |
|
|
//! FlashProtectSet() for possible values.
|
247 |
|
|
//
|
248 |
|
|
//*****************************************************************************
|
249 |
|
|
#if defined(GROUP_protectget) || defined(BUILD_ALL) || defined(DOXYGEN)
|
250 |
|
|
tFlashProtection
|
251 |
|
|
FlashProtectGet(unsigned long ulAddress)
|
252 |
|
|
{
|
253 |
|
|
unsigned long ulFMPRE, ulFMPPE;
|
254 |
|
|
|
255 |
|
|
//
|
256 |
|
|
// Check the argument.
|
257 |
|
|
//
|
258 |
|
|
ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
|
259 |
|
|
|
260 |
|
|
//
|
261 |
|
|
// Read the flash protection register and get the bits that apply to the
|
262 |
|
|
// specified block.
|
263 |
|
|
//
|
264 |
|
|
ulFMPRE = HWREG(FLASH_FMPRE);
|
265 |
|
|
ulFMPPE = HWREG(FLASH_FMPPE);
|
266 |
|
|
switch((((ulFMPRE >> (ulAddress / FLASH_PROTECT_SIZE)) &
|
267 |
|
|
FLASH_FMP_BLOCK_0) << 1) |
|
268 |
|
|
((ulFMPPE >> (ulAddress / FLASH_PROTECT_SIZE)) & FLASH_FMP_BLOCK_0))
|
269 |
|
|
{
|
270 |
|
|
//
|
271 |
|
|
// This block is marked as execute only (i.e. it can not be erased or
|
272 |
|
|
// programmed, and the only reads allowed are via the instruction fecth
|
273 |
|
|
// interface).
|
274 |
|
|
//
|
275 |
|
|
case 0:
|
276 |
|
|
case 1:
|
277 |
|
|
{
|
278 |
|
|
return(FlashExecuteOnly);
|
279 |
|
|
}
|
280 |
|
|
|
281 |
|
|
//
|
282 |
|
|
// This block is marked as read only (i.e. it can not be erased or
|
283 |
|
|
// programmed).
|
284 |
|
|
//
|
285 |
|
|
case 2:
|
286 |
|
|
{
|
287 |
|
|
return(FlashReadOnly);
|
288 |
|
|
}
|
289 |
|
|
|
290 |
|
|
//
|
291 |
|
|
// This block is read/write; it can be read, erased, and programmed.
|
292 |
|
|
//
|
293 |
|
|
case 3:
|
294 |
|
|
default:
|
295 |
|
|
{
|
296 |
|
|
return(FlashReadWrite);
|
297 |
|
|
}
|
298 |
|
|
}
|
299 |
|
|
}
|
300 |
|
|
#endif
|
301 |
|
|
|
302 |
|
|
//*****************************************************************************
|
303 |
|
|
//
|
304 |
|
|
//! Sets the protection setting for a block of flash.
|
305 |
|
|
//!
|
306 |
|
|
//! \param ulAddress is the start address of the flash block to be protected.
|
307 |
|
|
//! \param eProtect is the protection to be applied to the block. Can be one
|
308 |
|
|
//! of \b FlashReadWrite, \b FlashReadOnly, or \b FlashExecuteOnly.
|
309 |
|
|
//!
|
310 |
|
|
//! This function will set the protection for the specified 2 kB block of
|
311 |
|
|
//! flash. Blocks which are read/write can be made read-only or execute-only.
|
312 |
|
|
//! Blocks which are read-only can be made execute-only. Blocks which are
|
313 |
|
|
//! execute-only cannot have their protection modified. Attempts to make the
|
314 |
|
|
//! block protection less stringent (i.e. read-only to read/write) will result
|
315 |
|
|
//! in a failure (and be prevented by the hardware).
|
316 |
|
|
//!
|
317 |
|
|
//! Changes to the flash protection are maintained only until the next reset.
|
318 |
|
|
//! This allows the application to be executed in the desired flash protection
|
319 |
|
|
//! environment to check for inappropriate flash access (via the flash
|
320 |
|
|
//! interrupt). To make the flash protection permanent, use the
|
321 |
|
|
//! FlashProtectSave() function.
|
322 |
|
|
//!
|
323 |
|
|
//! \return Returns 0 on success, or -1 if an invalid address or an invalid
|
324 |
|
|
//! protection was specified.
|
325 |
|
|
//
|
326 |
|
|
//*****************************************************************************
|
327 |
|
|
#if defined(GROUP_protectset) || defined(BUILD_ALL) || defined(DOXYGEN)
|
328 |
|
|
long
|
329 |
|
|
FlashProtectSet(unsigned long ulAddress, tFlashProtection eProtect)
|
330 |
|
|
{
|
331 |
|
|
unsigned long ulProtectRE, ulProtectPE;
|
332 |
|
|
|
333 |
|
|
//
|
334 |
|
|
// Check the argument.
|
335 |
|
|
//
|
336 |
|
|
ASSERT(!(ulAddress & (FLASH_PROTECT_SIZE - 1)));
|
337 |
|
|
ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
|
338 |
|
|
(eProtect == FlashExecuteOnly));
|
339 |
|
|
|
340 |
|
|
//
|
341 |
|
|
// Convert the address into a block number.
|
342 |
|
|
//
|
343 |
|
|
ulAddress /= FLASH_PROTECT_SIZE;
|
344 |
|
|
|
345 |
|
|
//
|
346 |
|
|
// Get the current protection.
|
347 |
|
|
//
|
348 |
|
|
ulProtectRE = HWREG(FLASH_FMPRE);
|
349 |
|
|
ulProtectPE = HWREG(FLASH_FMPPE);
|
350 |
|
|
|
351 |
|
|
//
|
352 |
|
|
// Set the protection based on the requested proection.
|
353 |
|
|
//
|
354 |
|
|
switch(eProtect)
|
355 |
|
|
{
|
356 |
|
|
//
|
357 |
|
|
// Make this block execute only.
|
358 |
|
|
//
|
359 |
|
|
case FlashExecuteOnly:
|
360 |
|
|
{
|
361 |
|
|
//
|
362 |
|
|
// Turn off the read and program bits for this block.
|
363 |
|
|
//
|
364 |
|
|
ulProtectRE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
|
365 |
|
|
ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
|
366 |
|
|
|
367 |
|
|
//
|
368 |
|
|
// We're done handling this protection.
|
369 |
|
|
//
|
370 |
|
|
break;
|
371 |
|
|
}
|
372 |
|
|
|
373 |
|
|
//
|
374 |
|
|
// Make this block read only.
|
375 |
|
|
//
|
376 |
|
|
case FlashReadOnly:
|
377 |
|
|
{
|
378 |
|
|
//
|
379 |
|
|
// The block can not be made read only if it is execute only.
|
380 |
|
|
//
|
381 |
|
|
if(((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
|
382 |
|
|
FLASH_FMP_BLOCK_0)
|
383 |
|
|
{
|
384 |
|
|
return(-1);
|
385 |
|
|
}
|
386 |
|
|
|
387 |
|
|
//
|
388 |
|
|
// Make this block read only.
|
389 |
|
|
//
|
390 |
|
|
ulProtectPE &= ~(FLASH_FMP_BLOCK_0 << ulAddress);
|
391 |
|
|
|
392 |
|
|
//
|
393 |
|
|
// We're done handling this protection.
|
394 |
|
|
//
|
395 |
|
|
break;
|
396 |
|
|
}
|
397 |
|
|
|
398 |
|
|
//
|
399 |
|
|
// Make this block read/write.
|
400 |
|
|
//
|
401 |
|
|
case FlashReadWrite:
|
402 |
|
|
default:
|
403 |
|
|
{
|
404 |
|
|
//
|
405 |
|
|
// The block can not be made read/write if it is not already
|
406 |
|
|
// read/write.
|
407 |
|
|
//
|
408 |
|
|
if((((ulProtectRE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
|
409 |
|
|
FLASH_FMP_BLOCK_0) ||
|
410 |
|
|
(((ulProtectPE >> ulAddress) & FLASH_FMP_BLOCK_0) !=
|
411 |
|
|
FLASH_FMP_BLOCK_0))
|
412 |
|
|
{
|
413 |
|
|
return(-1);
|
414 |
|
|
}
|
415 |
|
|
|
416 |
|
|
//
|
417 |
|
|
// The block is already read/write, so there is nothing to do.
|
418 |
|
|
//
|
419 |
|
|
return(0);
|
420 |
|
|
}
|
421 |
|
|
}
|
422 |
|
|
|
423 |
|
|
//
|
424 |
|
|
// Set the new protection.
|
425 |
|
|
//
|
426 |
|
|
HWREG(FLASH_FMPRE) = ulProtectRE;
|
427 |
|
|
HWREG(FLASH_FMPPE) = ulProtectPE;
|
428 |
|
|
|
429 |
|
|
//
|
430 |
|
|
// Success.
|
431 |
|
|
//
|
432 |
|
|
return(0);
|
433 |
|
|
}
|
434 |
|
|
#endif
|
435 |
|
|
|
436 |
|
|
//*****************************************************************************
|
437 |
|
|
//
|
438 |
|
|
//! Saves the flash protection settings.
|
439 |
|
|
//!
|
440 |
|
|
//! This function will make the currently programmed flash protection settings
|
441 |
|
|
//! permanent. This is a non-reversible operation; a chip reset or power cycle
|
442 |
|
|
//! will not change the flash protection.
|
443 |
|
|
//!
|
444 |
|
|
//! This function will not return until the protection has been saved.
|
445 |
|
|
//!
|
446 |
|
|
//! \return Returns 0 on success, or -1 if a hardware error is encountered.
|
447 |
|
|
//
|
448 |
|
|
//*****************************************************************************
|
449 |
|
|
#if defined(GROUP_protectsave) || defined(BUILD_ALL) || defined(DOXYGEN)
|
450 |
|
|
long
|
451 |
|
|
FlashProtectSave(void)
|
452 |
|
|
{
|
453 |
|
|
//
|
454 |
|
|
// Tell the flash controller to write the flash read protection register.
|
455 |
|
|
//
|
456 |
|
|
HWREG(FLASH_FMA) = 0;
|
457 |
|
|
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
|
458 |
|
|
|
459 |
|
|
//
|
460 |
|
|
// Wait until the write has completed.
|
461 |
|
|
//
|
462 |
|
|
while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
|
463 |
|
|
{
|
464 |
|
|
}
|
465 |
|
|
|
466 |
|
|
//
|
467 |
|
|
// Tell the flash controller to write the flash program protection
|
468 |
|
|
// register.
|
469 |
|
|
//
|
470 |
|
|
HWREG(FLASH_FMA) = 1;
|
471 |
|
|
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_COMT;
|
472 |
|
|
|
473 |
|
|
//
|
474 |
|
|
// Wait until the write has completed.
|
475 |
|
|
//
|
476 |
|
|
while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
|
477 |
|
|
{
|
478 |
|
|
}
|
479 |
|
|
|
480 |
|
|
//
|
481 |
|
|
// Success.
|
482 |
|
|
//
|
483 |
|
|
return(0);
|
484 |
|
|
}
|
485 |
|
|
#endif
|
486 |
|
|
|
487 |
|
|
//*****************************************************************************
|
488 |
|
|
//
|
489 |
|
|
//! Registers an interrupt handler for the flash interrupt.
|
490 |
|
|
//!
|
491 |
|
|
//! \param pfnHandler is a pointer to the function to be called when the flash
|
492 |
|
|
//! interrupt occurs.
|
493 |
|
|
//!
|
494 |
|
|
//! This sets the handler to be called when the flash interrupt occurs. The
|
495 |
|
|
//! flash controller can generate an interrupt when an invalid flash access
|
496 |
|
|
//! occurs, such as trying to program or erase a read-only block, or trying to
|
497 |
|
|
//! read from an execute-only block. It can also generate an interrupt when a
|
498 |
|
|
//! program or erase operation has completed. The interrupt will be
|
499 |
|
|
//! automatically enabled when the handler is registered.
|
500 |
|
|
//!
|
501 |
|
|
//! \sa IntRegister() for important information about registering interrupt
|
502 |
|
|
//! handlers.
|
503 |
|
|
//!
|
504 |
|
|
//! \return None.
|
505 |
|
|
//
|
506 |
|
|
//*****************************************************************************
|
507 |
|
|
#if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN)
|
508 |
|
|
void
|
509 |
|
|
FlashIntRegister(void (*pfnHandler)(void))
|
510 |
|
|
{
|
511 |
|
|
//
|
512 |
|
|
// Register the interrupt handler, returning an error if an error occurs.
|
513 |
|
|
//
|
514 |
|
|
IntRegister(INT_FLASH, pfnHandler);
|
515 |
|
|
|
516 |
|
|
//
|
517 |
|
|
// Enable the flash interrupt.
|
518 |
|
|
//
|
519 |
|
|
IntEnable(INT_FLASH);
|
520 |
|
|
}
|
521 |
|
|
#endif
|
522 |
|
|
|
523 |
|
|
//*****************************************************************************
|
524 |
|
|
//
|
525 |
|
|
//! Unregisters the interrupt handler for the flash interrupt.
|
526 |
|
|
//!
|
527 |
|
|
//! This function will clear the handler to be called when the flash interrupt
|
528 |
|
|
//! occurs. This will also mask off the interrupt in the interrupt controller
|
529 |
|
|
//! so that the interrupt handler is no longer called.
|
530 |
|
|
//!
|
531 |
|
|
//! \sa IntRegister() for important information about registering interrupt
|
532 |
|
|
//! handlers.
|
533 |
|
|
//!
|
534 |
|
|
//! \return None.
|
535 |
|
|
//
|
536 |
|
|
//*****************************************************************************
|
537 |
|
|
#if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN)
|
538 |
|
|
void
|
539 |
|
|
FlashIntUnregister(void)
|
540 |
|
|
{
|
541 |
|
|
//
|
542 |
|
|
// Disable the interrupt.
|
543 |
|
|
//
|
544 |
|
|
IntDisable(INT_FLASH);
|
545 |
|
|
|
546 |
|
|
//
|
547 |
|
|
// Unregister the interrupt handler.
|
548 |
|
|
//
|
549 |
|
|
IntUnregister(INT_FLASH);
|
550 |
|
|
}
|
551 |
|
|
#endif
|
552 |
|
|
|
553 |
|
|
//*****************************************************************************
|
554 |
|
|
//
|
555 |
|
|
//! Enables individual flash controller interrupt sources.
|
556 |
|
|
//!
|
557 |
|
|
//! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
|
558 |
|
|
//! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
|
559 |
|
|
//!
|
560 |
|
|
//! Enables the indicated flash controller interrupt sources. Only the sources
|
561 |
|
|
//! that are enabled can be reflected to the processor interrupt; disabled
|
562 |
|
|
//! sources have no effect on the processor.
|
563 |
|
|
//!
|
564 |
|
|
//! \return None.
|
565 |
|
|
//
|
566 |
|
|
//*****************************************************************************
|
567 |
|
|
#if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN)
|
568 |
|
|
void
|
569 |
|
|
FlashIntEnable(unsigned long ulIntFlags)
|
570 |
|
|
{
|
571 |
|
|
//
|
572 |
|
|
// Enable the specified interrupts.
|
573 |
|
|
//
|
574 |
|
|
HWREG(FLASH_FCIM) |= ulIntFlags;
|
575 |
|
|
}
|
576 |
|
|
#endif
|
577 |
|
|
|
578 |
|
|
//*****************************************************************************
|
579 |
|
|
//
|
580 |
|
|
//! Disables individual flash controller interrupt sources.
|
581 |
|
|
//!
|
582 |
|
|
//! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
|
583 |
|
|
//! Can be any of the \b FLASH_FCIM_PROGRAM or \b FLASH_FCIM_ACCESS values.
|
584 |
|
|
//!
|
585 |
|
|
//! Disables the indicated flash controller interrupt sources. Only the
|
586 |
|
|
//! sources that are enabled can be reflected to the processor interrupt;
|
587 |
|
|
//! disabled sources have no effect on the processor.
|
588 |
|
|
//!
|
589 |
|
|
//! \return None.
|
590 |
|
|
//
|
591 |
|
|
//*****************************************************************************
|
592 |
|
|
#if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN)
|
593 |
|
|
void
|
594 |
|
|
FlashIntDisable(unsigned long ulIntFlags)
|
595 |
|
|
{
|
596 |
|
|
//
|
597 |
|
|
// Disable the specified interrupts.
|
598 |
|
|
//
|
599 |
|
|
HWREG(FLASH_FCIM) &= ~(ulIntFlags);
|
600 |
|
|
}
|
601 |
|
|
#endif
|
602 |
|
|
|
603 |
|
|
//*****************************************************************************
|
604 |
|
|
//
|
605 |
|
|
//! Gets the current interrupt status.
|
606 |
|
|
//!
|
607 |
|
|
//! \param bMasked is false if the raw interrupt status is required and true if
|
608 |
|
|
//! the masked interrupt status is required.
|
609 |
|
|
//!
|
610 |
|
|
//! This returns the interrupt status for the flash controller. Either the raw
|
611 |
|
|
//! interrupt status or the status of interrupts that are allowed to reflect to
|
612 |
|
|
//! the processor can be returned.
|
613 |
|
|
//!
|
614 |
|
|
//! \return The current interrupt status, enumerated as a bit field of
|
615 |
|
|
//! \b FLASH_FCMISC_PROGRAM and \b FLASH_FCMISC_ACCESS.
|
616 |
|
|
//
|
617 |
|
|
//*****************************************************************************
|
618 |
|
|
#if defined(GROUP_intgetstatus) || defined(BUILD_ALL) || defined(DOXYGEN)
|
619 |
|
|
unsigned long
|
620 |
|
|
FlashIntGetStatus(tBoolean bMasked)
|
621 |
|
|
{
|
622 |
|
|
//
|
623 |
|
|
// Return either the interrupt status or the raw interrupt status as
|
624 |
|
|
// requested.
|
625 |
|
|
//
|
626 |
|
|
if(bMasked)
|
627 |
|
|
{
|
628 |
|
|
return(HWREG(FLASH_FCMISC));
|
629 |
|
|
}
|
630 |
|
|
else
|
631 |
|
|
{
|
632 |
|
|
return(HWREG(FLASH_FCRIS));
|
633 |
|
|
}
|
634 |
|
|
}
|
635 |
|
|
#endif
|
636 |
|
|
|
637 |
|
|
//*****************************************************************************
|
638 |
|
|
//
|
639 |
|
|
//! Clears flash controller interrupt sources.
|
640 |
|
|
//!
|
641 |
|
|
//! \param ulIntFlags is the bit mask of the interrupt sources to be cleared.
|
642 |
|
|
//! Can be any of the \b FLASH_FCMISC_PROGRAM or \b FLASH_FCMISC_ACCESS
|
643 |
|
|
//! values.
|
644 |
|
|
//!
|
645 |
|
|
//! The specified flash controller interrupt sources are cleared, so that they
|
646 |
|
|
//! no longer assert. This must be done in the interrupt handler to keep it
|
647 |
|
|
//! from being called again immediately upon exit.
|
648 |
|
|
//!
|
649 |
|
|
//! \return None.
|
650 |
|
|
//
|
651 |
|
|
//*****************************************************************************
|
652 |
|
|
#if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN)
|
653 |
|
|
void
|
654 |
|
|
FlashIntClear(unsigned long ulIntFlags)
|
655 |
|
|
{
|
656 |
|
|
//
|
657 |
|
|
// Clear the flash interrupt.
|
658 |
|
|
//
|
659 |
|
|
HWREG(FLASH_FCMISC) = ulIntFlags;
|
660 |
|
|
}
|
661 |
|
|
#endif
|
662 |
|
|
|
663 |
|
|
//*****************************************************************************
|
664 |
|
|
//
|
665 |
|
|
// Close the Doxygen group.
|
666 |
|
|
//! @}
|
667 |
|
|
//
|
668 |
|
|
//*****************************************************************************
|