1 //*****************************************************************************
2 //
3 // eeprom.c - Driver for programming the on-chip EEPROM.
4 //
5 // Copyright (c) 2010-2020 Texas Instruments Incorporated. All rights reserved.
6 // Software License Agreement
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 // Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright
16 // notice, this list of conditions and the following disclaimer in the
17 // documentation and/or other materials provided with the
18 // distribution.
19 //
20 // Neither the name of Texas Instruments Incorporated nor the names of
21 // its contributors may be used to endorse or promote products derived
22 // from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 // This is part of revision 2.2.0.295 of the Tiva Peripheral Driver Library.
37 //
38 //*****************************************************************************
39
40 #include <stdbool.h>
41 #include <stdint.h>
42 #include "inc/hw_eeprom.h"
43 #include "inc/hw_flash.h"
44 #include "inc/hw_ints.h"
45 #include "inc/hw_sysctl.h"
46 #include "inc/hw_types.h"
47 #include "driverlib/debug.h"
48 #include "driverlib/flash.h"
49 #include "driverlib/interrupt.h"
50 #include "driverlib/sysctl.h"
51 #include "driverlib/eeprom.h"
52
53 //*****************************************************************************
54 //
55 //! \addtogroup eeprom_api
56 //! @{
57 //
58 //*****************************************************************************
59
60 //*****************************************************************************
61 //
62 // Useful macros to extract the number of EEPROM blocks available on the target
63 // device and the total EEPROM storage in bytes from the EESIZE register.
64 //
65 //*****************************************************************************
66 #define BLOCKS_FROM_EESIZE(x) (((x) & EEPROM_EESIZE_BLKCNT_M) >> \
67 EEPROM_EESIZE_BLKCNT_S)
68 #define SIZE_FROM_EESIZE(x) ((((x) & EEPROM_EESIZE_WORDCNT_M) >> \
69 EEPROM_EESIZE_WORDCNT_S) * 4)
70
71 //*****************************************************************************
72 //
73 // Useful macro to extract the offset from a linear address.
74 //
75 //*****************************************************************************
76 #define OFFSET_FROM_ADDR(x) (((x) >> 2) & 0x0F)
77
78 //*****************************************************************************
79 //
80 // The key value required to initiate a mass erase.
81 //
82 //*****************************************************************************
83 #define EEPROM_MASS_ERASE_KEY ((uint32_t)0xE37B << EEPROM_EEDBGME_KEY_S)
84
85 //*****************************************************************************
86 //
87 // This function implements a workaround for a bug in Blizzard rev A silicon.
88 // It ensures that only the 1KB flash sector containing a given EEPROM address
89 // is erased if an erase/copy operation is required as a result of a following
90 // EEPROM write.
91 //
92 //*****************************************************************************
93 static void
_EEPROMSectorMaskSet(uint32_t ui32Address)94 _EEPROMSectorMaskSet(uint32_t ui32Address)
95 {
96 uint32_t ui32Mask;
97
98 //
99 // Determine which page contains the passed EEPROM address. The 2KB EEPROM
100 // is implemented in 16KB of flash with each 1KB sector of flash holding
101 // values for 32 consecutive EEPROM words (or 128 bytes).
102 //
103 ui32Mask = ~(1 << (ui32Address >> 7));
104
105 SysCtlDelay(10);
106 HWREG(0x400FD0FC) = 3;
107 SysCtlDelay(10);
108 HWREG(0x400AE2C0) = ui32Mask;
109 SysCtlDelay(10);
110 HWREG(0x400FD0FC) = 0;
111 SysCtlDelay(10);
112 }
113
114 //*****************************************************************************
115 //
116 // Clear the FSM sector erase mask to ensure that any following main array
117 // flash erase operations operate as expected.
118 //
119 //*****************************************************************************
120 static void
_EEPROMSectorMaskClear(void)121 _EEPROMSectorMaskClear(void)
122 {
123 SysCtlDelay(10);
124 HWREG(0x400FD0FC) = 3;
125 SysCtlDelay(10);
126 HWREG(0x400AE2C0) = 0;
127 SysCtlDelay(10);
128 HWREG(0x400FD0FC) = 0;
129 SysCtlDelay(10);
130 }
131
132 //*****************************************************************************
133 //
134 // Block until the EEPROM peripheral is not busy.
135 //
136 //*****************************************************************************
137 static void
_EEPROMWaitForDone(void)138 _EEPROMWaitForDone(void)
139 {
140 //
141 // Is the EEPROM still busy?
142 //
143 while(HWREG(EEPROM_EEDONE) & EEPROM_EEDONE_WORKING)
144 {
145 //
146 // Spin while EEPROM is busy.
147 //
148 }
149 }
150
151 //*****************************************************************************
152 //
153 //! Performs any necessary recovery in case of power failures during write.
154 //!
155 //! This function \b must be called after SysCtlPeripheralEnable() and before
156 //! the EEPROM is accessed. It is used to check for errors in the EEPROM state
157 //! such as from power failure during a previous write operation. The function
158 //! detects these errors and performs as much recovery as possible.
159 //!
160 //! If \b EEPROM_INIT_ERROR is returned, the EEPROM was unable to recover its
161 //! state. If power is stable when this occurs, this indicates a fatal
162 //! error and is likely an indication that the EEPROM memory has exceeded its
163 //! specified lifetime write/erase specification. If the supply voltage is
164 //! unstable when this return code is observed, retrying the operation once the
165 //! voltage is stabilized may clear the error.
166 //!
167 //! Failure to call this function after a reset may lead to incorrect operation
168 //! or permanent data loss if the EEPROM is later written.
169 //!
170 //! \return Returns \b EEPROM_INIT_OK if no errors were detected or \b
171 //! EEPROM_INIT_ERROR if the EEPROM peripheral cannot currently recover from
172 //! an interrupted write or erase operation.
173 //
174 //*****************************************************************************
175 uint32_t
EEPROMInit(void)176 EEPROMInit(void)
177 {
178 uint32_t ui32Status;
179
180 //
181 // Insert a small delay (6 cycles + call overhead) to guard against the
182 // possibility that this function is called immediately after the EEPROM
183 // peripheral is enabled. Without this delay, there is a slight chance
184 // that the first EEPROM register read will fault if you are using a
185 // compiler with a ridiculously good optimizer!
186 //
187 SysCtlDelay(2);
188
189 //
190 // Make sure the EEPROM has finished any ongoing processing.
191 //
192 _EEPROMWaitForDone();
193
194 //
195 // Read the EESUPP register to see if any errors have been reported.
196 //
197 ui32Status = HWREG(EEPROM_EESUPP);
198
199 //
200 // Did an error of some sort occur during initialization?
201 //
202 if(ui32Status & (EEPROM_EESUPP_PRETRY | EEPROM_EESUPP_ERETRY))
203 {
204 return(EEPROM_INIT_ERROR);
205 }
206
207 //
208 // Perform a second EEPROM reset.
209 //
210 SysCtlPeripheralReset(SYSCTL_PERIPH_EEPROM0);
211
212 //
213 // Wait for the EEPROM to complete its reset processing once again.
214 //
215 SysCtlDelay(2);
216 _EEPROMWaitForDone();
217
218 //
219 // Read EESUPP once again to determine if any error occurred.
220 //
221 ui32Status = HWREG(EEPROM_EESUPP);
222
223 //
224 // Was an error reported following the second reset?
225 //
226 if(ui32Status & (EEPROM_EESUPP_PRETRY | EEPROM_EESUPP_ERETRY))
227 {
228 return(EEPROM_INIT_ERROR);
229 }
230
231 //
232 // The EEPROM does not indicate that any error occurred.
233 //
234 return(EEPROM_INIT_OK);
235 }
236
237
238 //*****************************************************************************
239 //
240 //! Determines the size of the EEPROM.
241 //!
242 //! This function returns the size of the EEPROM in bytes.
243 //!
244 //! \return Returns the total number of bytes in the EEPROM.
245 //
246 //*****************************************************************************
247 uint32_t
EEPROMSizeGet(void)248 EEPROMSizeGet(void)
249 {
250 //
251 // Return the size of the EEPROM in bytes.
252 //
253 return(SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
254 }
255
256 //*****************************************************************************
257 //
258 //! Determines the number of blocks in the EEPROM.
259 //!
260 //! This function may be called to determine the number of blocks in the
261 //! EEPROM. Each block is the same size and the number of bytes of storage
262 //! contained in a block may be determined by dividing the size of the device,
263 //! obtained via a call to the EEPROMSizeGet() function, by the number of
264 //! blocks returned by this function.
265 //!
266 //! \return Returns the total number of blocks in the device EEPROM.
267 //
268 //*****************************************************************************
269 uint32_t
EEPROMBlockCountGet(void)270 EEPROMBlockCountGet(void)
271 {
272 //
273 // Extract the number of blocks and return it to the caller.
274 //
275 #ifdef EEPROM_SIZE_LIMIT
276 //
277 // If a size limit has been specified, fake the number of blocks to match.
278 //
279 return(EEPROM_SIZE_LIMIT / 48);
280 #else
281 //
282 // Return the actual number of blocks supported by the hardware.
283 //
284 return(BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
285 #endif
286 }
287
288 //*****************************************************************************
289 //
290 //! Reads data from the EEPROM.
291 //!
292 //! \param pui32Data is a pointer to storage for the data read from the EEPROM.
293 //! This pointer must point to at least \e ui32Count bytes of available memory.
294 //! \param ui32Address is the byte address within the EEPROM from which data is
295 //! to be read. This value must be a multiple of 4.
296 //! \param ui32Count is the number of bytes of data to read from the EEPROM.
297 //! This value must be a multiple of 4.
298 //!
299 //! This function may be called to read a number of words of data from a
300 //! word-aligned address within the EEPROM. Data read is copied into the
301 //! buffer pointed to by the \e pui32Data parameter.
302 //!
303 //! \return None.
304 //
305 //*****************************************************************************
306 void
EEPROMRead(uint32_t * pui32Data,uint32_t ui32Address,uint32_t ui32Count)307 EEPROMRead(uint32_t *pui32Data, uint32_t ui32Address, uint32_t ui32Count)
308 {
309 //
310 // Check parameters in a debug build.
311 //
312 ASSERT(pui32Data);
313 ASSERT(ui32Address < SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
314 ASSERT((ui32Address + ui32Count) <=
315 SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
316 ASSERT((ui32Address & 3) == 0);
317 ASSERT((ui32Count & 3) == 0);
318
319 //
320 // Set the block and offset appropriately to read the first word.
321 //
322 HWREG(EEPROM_EEBLOCK) = EEPROMBlockFromAddr(ui32Address);
323 HWREG(EEPROM_EEOFFSET) = OFFSET_FROM_ADDR(ui32Address);
324
325 //
326 // Convert the byte count to a word count.
327 //
328 ui32Count /= 4;
329
330 //
331 // Read each word in turn.
332 //
333 while(ui32Count)
334 {
335 //
336 // Read the next word through the autoincrementing register.
337 //
338 *pui32Data = HWREG(EEPROM_EERDWRINC);
339
340 //
341 // Move on to the next word.
342 //
343 pui32Data++;
344 ui32Count--;
345
346 //
347 // Do we need to move to the next block? This is the case if the
348 // offset register has just wrapped back to 0. Note that we only
349 // write the block register if we have more data to read. If this
350 // register is written, the hardware expects a read or write operation
351 // next. If a mass erase is requested instead, the mass erase will
352 // fail.
353 //
354 if(ui32Count && (HWREG(EEPROM_EEOFFSET) == 0))
355 {
356 HWREG(EEPROM_EEBLOCK) += 1;
357 }
358 }
359 }
360
361 //*****************************************************************************
362 //
363 //! Writes data to the EEPROM.
364 //!
365 //! \param pui32Data points to the first word of data to write to the EEPROM.
366 //! \param ui32Address defines the byte address within the EEPROM that the data
367 //! is to be written to. This value must be a multiple of 4.
368 //! \param ui32Count defines the number of bytes of data that is to be written.
369 //! This value must be a multiple of 4.
370 //!
371 //! This function may be called to write data into the EEPROM at a given
372 //! word-aligned address. The call is synchronous and returns only after
373 //! all data has been written or an error occurs.
374 //!
375 //! \return Returns 0 on success or non-zero values on failure. Failure codes
376 //! are logical OR combinations of \b EEPROM_RC_WRBUSY, \b EEPROM_RC_NOPERM,
377 //! \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE, and \b EEPROM_RC_WORKING.
378 //
379 //*****************************************************************************
380 uint32_t
EEPROMProgram(uint32_t * pui32Data,uint32_t ui32Address,uint32_t ui32Count)381 EEPROMProgram(uint32_t *pui32Data, uint32_t ui32Address, uint32_t ui32Count)
382 {
383 uint32_t ui32Status;
384
385 //
386 // Check parameters in a debug build.
387 //
388 ASSERT(pui32Data);
389 ASSERT(ui32Address < SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
390 ASSERT((ui32Address + ui32Count) <=
391 SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
392 ASSERT((ui32Address & 3) == 0);
393 ASSERT((ui32Count & 3) == 0);
394
395 //
396 // Make sure the EEPROM is idle before we start.
397 //
398 do
399 {
400 //
401 // Read the status.
402 //
403 ui32Status = HWREG(EEPROM_EEDONE);
404 }
405 while(ui32Status & EEPROM_EEDONE_WORKING);
406
407 //
408 // Set the block and offset appropriately to program the first word.
409 //
410 HWREG(EEPROM_EEBLOCK) = EEPROMBlockFromAddr(ui32Address);
411 HWREG(EEPROM_EEOFFSET) = OFFSET_FROM_ADDR(ui32Address);
412
413 //
414 // Convert the byte count to a word count.
415 //
416 ui32Count /= 4;
417
418 //
419 // Write each word in turn.
420 //
421 while(ui32Count)
422 {
423 //
424 // This is a workaround for a silicon problem on Blizzard rev A. We
425 // need to do this before every word write to ensure that we don't
426 // have problems in multi-word writes that span multiple flash sectors.
427 //
428 if(CLASS_IS_TM4C123 && REVISION_IS_A0)
429 {
430 _EEPROMSectorMaskSet(ui32Address);
431 }
432
433 //
434 // Write the next word through the autoincrementing register.
435 //
436 HWREG(EEPROM_EERDWRINC) = *pui32Data;
437
438 //
439 // Wait a few cycles. In some cases, the WRBUSY bit is not set
440 // immediately and this prevents us from dropping through the polling
441 // loop before the bit is set.
442 //
443 SysCtlDelay(10);
444
445 //
446 // Wait for the write to complete.
447 //
448 do
449 {
450 //
451 // Read the status.
452 //
453 ui32Status = HWREG(EEPROM_EEDONE);
454 }
455 while(ui32Status & EEPROM_EEDONE_WORKING);
456
457 //
458 // Make sure we completed the write without errors. Note that we
459 // must check this per-word because write permission can be set per
460 // block resulting in only a section of the write not being performed.
461 //
462 if(ui32Status & EEPROM_EEDONE_NOPERM)
463 {
464 //
465 // An error was reported that would prevent the values from
466 // being written correctly.
467 //
468 if(CLASS_IS_TM4C123 && REVISION_IS_A0)
469 {
470 _EEPROMSectorMaskClear();
471 }
472 return(ui32Status);
473 }
474
475 //
476 // Move on to the next word.
477 //
478 pui32Data++;
479 ui32Count--;
480
481 //
482 // Do we need to move to the next block? This is the case if the
483 // offset register has just wrapped back to 0. Note that we only
484 // write the block register if we have more data to read. If this
485 // register is written, the hardware expects a read or write operation
486 // next. If a mass erase is requested instead, the mass erase will
487 // fail.
488 //
489 if(ui32Count && (HWREG(EEPROM_EEOFFSET) == 0))
490 {
491 HWREG(EEPROM_EEBLOCK) += 1;
492 }
493 }
494
495 //
496 // Clear the sector protection bits to prevent possible problems when
497 // programming the main flash array later.
498 //
499 if(CLASS_IS_TM4C123 && REVISION_IS_A0)
500 {
501 _EEPROMSectorMaskClear();
502 }
503
504 //
505 // Return the current status to the caller.
506 //
507 return(HWREG(EEPROM_EEDONE));
508 }
509
510 //*****************************************************************************
511 //
512 //! Writes a word to the EEPROM.
513 //!
514 //! \param ui32Data is the word to write to the EEPROM.
515 //! \param ui32Address defines the byte address within the EEPROM to which the
516 //! data is to be written. This value must be a multiple of 4.
517 //!
518 //! This function is intended to allow EEPROM programming under interrupt
519 //! control. It may be called to start the process of writing a single word of
520 //! data into the EEPROM at a given word-aligned address. The call is
521 //! asynchronous and returns immediately without waiting for the write to
522 //! complete. Completion of the operation is signaled by means of an
523 //! interrupt from the EEPROM module. The EEPROM peripheral shares a single
524 //! interrupt vector with the flash memory subsystem, \b INT_FLASH.
525 //!
526 //! \return Returns status and error information in the form of a logical OR
527 //! combinations of \b EEPROM_RC_WRBUSY, \b EEPROM_RC_NOPERM,
528 //! \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE and \b EEPROM_RC_WORKING. Flags
529 //! \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE, and \b EEPROM_RC_WORKING are
530 //! expected in normal operation and do not indicate an error.
531 //
532 //*****************************************************************************
533 uint32_t
EEPROMProgramNonBlocking(uint32_t ui32Data,uint32_t ui32Address)534 EEPROMProgramNonBlocking(uint32_t ui32Data, uint32_t ui32Address)
535 {
536 //
537 // Check parameters in a debug build.
538 //
539 ASSERT(ui32Address < SIZE_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
540 ASSERT((ui32Address & 3) == 0);
541
542 //
543 // This is a workaround for a silicon problem on Blizzard rev A.
544 //
545 if(CLASS_IS_TM4C123 && REVISION_IS_A0)
546 {
547 _EEPROMSectorMaskSet(ui32Address);
548 }
549
550 //
551 // Set the block and offset appropriately to program the desired word.
552 //
553 HWREG(EEPROM_EEBLOCK) = EEPROMBlockFromAddr(ui32Address);
554 HWREG(EEPROM_EEOFFSET) = OFFSET_FROM_ADDR(ui32Address);
555
556 //
557 // Write the new word using the auto-incrementing register just in case
558 // the caller wants to write follow-on words using direct register access
559 //
560 HWREG(EEPROM_EERDWRINC) = ui32Data;
561
562 //
563 // Return the current status to the caller.
564 //
565 return(HWREG(EEPROM_EEDONE));
566 }
567
568 //*****************************************************************************
569 //
570 //! Erases the EEPROM and returns it to the factory default condition.
571 //!
572 //! This function completely erases the EEPROM and removes any and
573 //! all access protection on its blocks, leaving the device in the factory
574 //! default condition. After this operation, all EEPROM words contain the
575 //! value 0xFFFFFFFF and all blocks are accessible for both read and write
576 //! operations in all CPU modes. No passwords are active.
577 //!
578 //! The function is synchronous and does not return until the erase operation
579 //! has completed.
580 //!
581 //! \return Returns 0 on success or non-zero values on failure. Failure codes
582 //! are logical OR combinations of \b EEPROM_RC_WRBUSY, \b EEPROM_RC_NOPERM,
583 //! \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE, and \b EEPROM_RC_WORKING.
584 //
585 //*****************************************************************************
586 uint32_t
EEPROMMassErase(void)587 EEPROMMassErase(void)
588 {
589 //
590 // This is a workaround for a silicon problem on Blizzard rev A.
591 //
592 if(CLASS_IS_TM4C123 && REVISION_IS_A0)
593 {
594 _EEPROMSectorMaskClear();
595 }
596
597 //
598 // Start the mass erase processing
599 //
600 HWREG(EEPROM_EEDBGME) = EEPROM_MASS_ERASE_KEY | EEPROM_EEDBGME_ME;
601
602 //
603 // Wait for completion.
604 //
605 _EEPROMWaitForDone();
606
607 //
608 // Reset the peripheral. This is required so that all protection
609 // mechanisms and passwords are reset now that the EEPROM data has been
610 // scrubbed.
611 //
612 SysCtlPeripheralReset(SYSCTL_PERIPH_EEPROM0);
613
614 //
615 // Wait for completion again.
616 //
617 SysCtlDelay(2);
618 _EEPROMWaitForDone();
619
620 //
621 // Pass any error codes back to the caller.
622 //
623 return(HWREG(EEPROM_EEDONE));
624 }
625
626 //*****************************************************************************
627 //
628 //! Returns the current protection level for an EEPROM block.
629 //!
630 //! \param ui32Block is the block number for which the protection level is to
631 //! be queried.
632 //!
633 //! This function returns the current protection settings for a given
634 //! EEPROM block. If block 0 is currently locked, it must be unlocked prior
635 //! to calling this function to query the protection setting for other blocks.
636 //!
637 //! \return Returns one of \b EEPROM_PROT_RW_LRO_URW, \b EEPROM_PROT_NA_LNA_URW
638 //! or \b EEPROM_PROT_RO_LNA_URO optionally OR-ed with
639 //! \b EEPROM_PROT_SUPERVISOR_ONLY.
640 //
641 //*****************************************************************************
642 uint32_t
EEPROMBlockProtectGet(uint32_t ui32Block)643 EEPROMBlockProtectGet(uint32_t ui32Block)
644 {
645 //
646 // Parameter validity check.
647 //
648 ASSERT(ui32Block < BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
649
650 //
651 // Set the current block.
652 //
653 HWREG(EEPROM_EEBLOCK) = ui32Block;
654
655 //
656 // Return the protection flags for this block.
657 //
658 return(HWREG(EEPROM_EEPROT));
659 }
660
661 //*****************************************************************************
662 //
663 //! Set the current protection options for an EEPROM block.
664 //!
665 //! \param ui32Block is the block number for which the protection options are
666 //! to be set.
667 //! \param ui32Protect consists of one of the values \b EEPROM_PROT_RW_LRO_URW,
668 //! \b EEPROM_PROT_NA_LNA_URW or \b EEPROM_PROT_RO_LNA_URO optionally ORed with
669 //! \b EEPROM_PROT_SUPERVISOR_ONLY.
670 //!
671 //! This function sets the protection settings for a given EEPROM block
672 //! assuming no protection settings have previously been written. Note that
673 //! protection settings applied to block 0 have special meaning and control
674 //! access to the EEPROM peripheral as a whole. Protection settings applied to
675 //! blocks numbered 1 and above are layered above any protection set on block 0
676 //! such that the effective protection on each block is the logical OR of the
677 //! protection flags set for block 0 and for the target block. This protocol
678 //! allows global protection options to be set for the whole device via block
679 //! 0 and more restrictive protection settings to be set on a block-by-block
680 //! basis.
681 //!
682 //! The protection flags indicate access permissions as follow:
683 //!
684 //! \b EEPROM_PROT_SUPERVISOR_ONLY restricts access to the block to threads
685 //! running in supervisor mode. If clear, both user and supervisor threads
686 //! can access the block.
687 //!
688 //! \b EEPROM_PROT_RW_LRO_URW provides read/write access to the block if no
689 //! password is set or if a password is set and the block is unlocked. If the
690 //! block is locked, only read access is permitted.
691 //!
692 //! \b EEPROM_PROT_NA_LNA_URW provides neither read nor write access unless
693 //! a password is set and the block is unlocked. If the block is unlocked,
694 //! both read and write access are permitted.
695 //!
696 //! \b EEPROM_PROT_RO_LNA_URO provides read access to the block if no password
697 //! is set or if a password is set and the block is unlocked. If the block is
698 //! password protected and locked, neither read nor write access is permitted.
699 //!
700 //! \return Returns a logical OR combination of \b EEPROM_RC_WRBUSY, \b
701 //! EEPROM_RC_NOPERM, \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE, and \b
702 //! EEPROM_RC_WORKING to indicate status and error conditions.
703 //
704 //*****************************************************************************
705 uint32_t
EEPROMBlockProtectSet(uint32_t ui32Block,uint32_t ui32Protect)706 EEPROMBlockProtectSet(uint32_t ui32Block, uint32_t ui32Protect)
707 {
708 //
709 // Parameter validity check.
710 //
711 ASSERT(ui32Block < BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
712
713 //
714 // Set the current block.
715 //
716 HWREG(EEPROM_EEBLOCK) = ui32Block;
717
718 //
719 // Set the protection options for this block.
720 //
721 HWREG(EEPROM_EEPROT) = ui32Protect;
722
723 //
724 // Wait for the write to complete.
725 //
726 while(HWREG(EEPROM_EEDONE) & EEPROM_EEDONE_WORKING)
727 {
728 //
729 // Still working.
730 //
731 }
732
733 //
734 // Pass any error codes back to the caller.
735 //
736 return(HWREG(EEPROM_EEDONE));
737 }
738
739 //*****************************************************************************
740 //
741 //! Sets the password used to protect an EEPROM block.
742 //!
743 //! \param ui32Block is the EEPROM block number for which the password is to be
744 //! set.
745 //! \param pui32Password points to an array of uint32_t values comprising
746 //! the password to set. Each element may be any 32-bit value other than
747 //! 0xFFFFFFFF. This array must contain the number of elements given by the
748 //! \e ui32Count parameter.
749 //! \param ui32Count provides the number of uint32_ts in the \e ui32Password.
750 //! Valid values are 1, 2 and 3.
751 //!
752 //! This function allows the password used to unlock an EEPROM block to be
753 //! set. Valid passwords may be either 32, 64 or 96 bits comprising words
754 //! with any value other than 0xFFFFFFFF. The password may only be set once.
755 //! Any further attempts to set the password result in an error. Once the
756 //! password is set, the block remains unlocked until EEPROMBlockLock() is
757 //! called for that block or block 0, or a reset occurs.
758 //!
759 //! If a password is set on block 0, this affects locking of the peripheral as
760 //! a whole. When block 0 is locked, all other EEPROM blocks are inaccessible
761 //! until block 0 is unlocked. Once block 0 is unlocked, other blocks
762 //! become accessible according to any passwords set on those blocks and the
763 //! protection set for that block via a call to EEPROMBlockProtectSet().
764 //!
765 //! \return Returns a logical OR combination of \b EEPROM_RC_WRBUSY, \b
766 //! EEPROM_RC_NOPERM, \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE, and \b
767 //! EEPROM_RC_WORKING to indicate status and error conditions.
768 //
769 //*****************************************************************************
770 uint32_t
EEPROMBlockPasswordSet(uint32_t ui32Block,uint32_t * pui32Password,uint32_t ui32Count)771 EEPROMBlockPasswordSet(uint32_t ui32Block, uint32_t *pui32Password,
772 uint32_t ui32Count)
773 {
774 uint32_t ui32Reg;
775
776 //
777 // Check parameters in a debug build.
778 //
779 ASSERT(pui32Password);
780 ASSERT(ui32Block < BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
781 ASSERT(ui32Count <= 3);
782
783 //
784 // Set the block number whose password we are about to write.
785 //
786 HWREG(EEPROM_EEBLOCK) = ui32Block;
787
788 //
789 // Start with the first password word.
790 //
791 ui32Reg = EEPROM_EEPASS0;
792
793 //
794 // Write the password.
795 //
796 while(ui32Count)
797 {
798 //
799 // Start the process of writing the password.
800 //
801 HWREG(ui32Reg) = *pui32Password;
802
803 //
804 // Update values in preparation for writing the next word.
805 //
806 pui32Password++;
807 ui32Reg += 4;
808 ui32Count--;
809
810 //
811 // Wait for the last word write to complete or an error to be reported.
812 //
813 while(HWREG(EEPROM_EEDONE) & EEPROM_EEDONE_WORKING)
814 {
815 //
816 // Still working.
817 //
818 }
819 }
820
821 //
822 // Return the final write status.
823 //
824 return(HWREG(EEPROM_EEDONE));
825 }
826
827 //*****************************************************************************
828 //
829 //! Locks a password-protected EEPROM block.
830 //!
831 //! \param ui32Block is the EEPROM block number which is to be locked.
832 //!
833 //! This function locks an EEPROM block that has previously been protected by
834 //! writing a password. Access to the block once it is locked is determined
835 //! by the protection settings applied via a previous call to the
836 //! EEPROMBlockProtectSet() function. If no password has previously been set
837 //! for the block, this function has no effect.
838 //!
839 //! Locking block 0 has the effect of making all other blocks in the EEPROM
840 //! inaccessible.
841 //!
842 //! \return Returns the lock state for the block on exit, 1 if unlocked (as
843 //! would be the case if no password was set) or 0 if locked.
844 //!
845 //*****************************************************************************
846 uint32_t
EEPROMBlockLock(uint32_t ui32Block)847 EEPROMBlockLock(uint32_t ui32Block)
848 {
849 //
850 // Check parameters in a debug build.
851 //
852 ASSERT(ui32Block < BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
853
854 //
855 // Select the block we are going to lock.
856 //
857 HWREG(EEPROM_EEBLOCK) = ui32Block;
858
859 //
860 // Lock the block.
861 //
862 HWREG(EEPROM_EEUNLOCK) = 0xFFFFFFFF;
863
864 //
865 // Return the current lock state.
866 //
867 return(HWREG(EEPROM_EEUNLOCK));
868 }
869
870 //*****************************************************************************
871 //
872 //! Unlocks a password-protected EEPROM block.
873 //!
874 //! \param ui32Block is the EEPROM block number which is to be unlocked.
875 //! \param pui32Password points to an array of uint32_t values containing
876 //! the password for the block. Each element must match the password
877 //! originally set via a call to EEPROMBlockPasswordSet().
878 //! \param ui32Count provides the number of elements in the \e pui32Password
879 //! array and must match the value originally passed to
880 //! EEPROMBlockPasswordSet(). Valid values are 1, 2 and 3.
881 //!
882 //! This function unlocks an EEPROM block that has previously been protected by
883 //! writing a password. Access to the block once it is unlocked is determined
884 //! by the protection settings applied via a previous call to the
885 //! EEPROMBlockProtectSet() function.
886 //!
887 //! To successfully unlock an EEPROM block, the password provided must match
888 //! the password provided on the original call to EEPROMBlockPasswordSet(). If
889 //! an incorrect password is provided, the block remains locked.
890 //!
891 //! Unlocking block 0 has the effect of making all other blocks in the device
892 //! accessible according to their own access protection settings. When block
893 //! 0 is locked, all other EEPROM blocks are inaccessible.
894 //!
895 //! \return Returns the lock state for the block on exit, 1 if unlocked or 0 if
896 //! locked.
897 //!
898 //*****************************************************************************
899 uint32_t
EEPROMBlockUnlock(uint32_t ui32Block,uint32_t * pui32Password,uint32_t ui32Count)900 EEPROMBlockUnlock(uint32_t ui32Block, uint32_t *pui32Password,
901 uint32_t ui32Count)
902 {
903 //
904 // Check parameters in a debug build.
905 //
906 ASSERT(pui32Password);
907 ASSERT(ui32Block < BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
908 ASSERT(ui32Count <= 3);
909
910 //
911 // Set the block that we are trying to unlock.
912 //
913 HWREG(EEPROM_EEBLOCK) = ui32Block;
914
915 //
916 // Write the unlock register with 0xFFFFFFFF to reset the unlock
917 // sequence just in case a short password was previously used to try to
918 // unlock the block.
919 //
920 HWREG(EEPROM_EEUNLOCK) = 0xFFFFFFFF;
921
922 //
923 // We need to write the password words in the opposite order when unlocking
924 // compared to locking so start at the end of the array.
925 //
926 pui32Password += (ui32Count - 1);
927
928 //
929 // Write the supplied password to unlock the block.
930 //
931 while(ui32Count)
932 {
933 HWREG(EEPROM_EEUNLOCK) = *pui32Password--;
934 ui32Count--;
935 }
936
937 //
938 // Let the caller know if their password worked.
939 //
940 return(HWREG(EEPROM_EEUNLOCK));
941 }
942
943 //*****************************************************************************
944 //
945 //! Hides an EEPROM block until the next reset.
946 //!
947 //! \param ui32Block is the EEPROM block number which is to be hidden.
948 //!
949 //! This function hides an EEPROM block other than block 0. Once hidden, a
950 //! block is completely inaccessible until the next reset. This mechanism
951 //! allows initialization code to have access to data which is to be hidden
952 //! from the rest of the application. Unlike applications using passwords, an
953 //! application making using of block hiding need not contain any embedded
954 //! passwords which could be found through disassembly.
955 //!
956 //! \return None.
957 //!
958 //*****************************************************************************
959 void
EEPROMBlockHide(uint32_t ui32Block)960 EEPROMBlockHide(uint32_t ui32Block)
961 {
962 //
963 // Check parameters in a debug build.
964 //
965 ASSERT(!ui32Block);
966 ASSERT(ui32Block < BLOCKS_FROM_EESIZE(HWREG(EEPROM_EESIZE)));
967
968 //
969 // Hide the requested block.
970 //
971 HWREG(EEPROM_EEHIDE) = (1 << ui32Block);
972 }
973
974 //*****************************************************************************
975 //
976 //! Enables the EEPROM interrupt.
977 //!
978 //! \param ui32IntFlags indicates which EEPROM interrupt source to enable.
979 //! This must be \b EEPROM_INT_PROGRAM currently.
980 //!
981 //! This function enables the EEPROM interrupt. When enabled, an interrupt
982 //! is generated when any EEPROM write or erase operation completes. The
983 //! EEPROM peripheral shares a single interrupt vector with the flash memory
984 //! subsystem, \b INT_FLASH. This function is provided as a convenience but
985 //! the EEPROM interrupt can also be enabled using a call to FlashIntEnable()
986 //! passing FLASH_INT_EEPROM in the \e ui32IntFlags parameter.
987 //!
988 //! \return None.
989 //!
990 //*****************************************************************************
991 void
EEPROMIntEnable(uint32_t ui32IntFlags)992 EEPROMIntEnable(uint32_t ui32IntFlags)
993 {
994 //
995 // Look for valid interrupt sources.
996 //
997 ASSERT(ui32IntFlags == EEPROM_INT_PROGRAM);
998
999 //
1000 // Enable interrupts from the EEPROM module.
1001 //
1002 HWREG(EEPROM_EEINT) |= EEPROM_EEINT_INT;
1003
1004 //
1005 // Enable the EEPROM interrupt in the flash controller module.
1006 //
1007 HWREG(FLASH_FCIM) |= FLASH_FCRIS_ERIS;
1008 }
1009
1010 //*****************************************************************************
1011 //
1012 //! Disables the EEPROM interrupt.
1013 //!
1014 //! \param ui32IntFlags indicates which EEPROM interrupt source to disable.
1015 //! This must be \b EEPROM_INT_PROGRAM currently.
1016 //!
1017 //! This function disables the EEPROM interrupt and prevents calls to the
1018 //! interrupt vector when any EEPROM write or erase operation completes. The
1019 //! EEPROM peripheral shares a single interrupt vector with the flash memory
1020 //! subsystem, \b INT_FLASH. This function is provided as a convenience but
1021 //! the EEPROM interrupt can also be disabled using a call to FlashIntDisable()
1022 //! passing FLASH_INT_EEPROM in the \e ui32IntFlags parameter.
1023 //!
1024 //! \return None.
1025 //!
1026 //*****************************************************************************
1027 void
EEPROMIntDisable(uint32_t ui32IntFlags)1028 EEPROMIntDisable(uint32_t ui32IntFlags)
1029 {
1030 //
1031 // Look for valid interrupt sources.
1032 //
1033 ASSERT(ui32IntFlags == EEPROM_INT_PROGRAM);
1034
1035 //
1036 // Disable the EEPROM interrupt in the flash controller module.
1037 //
1038 HWREG(FLASH_FCIM) &= ~FLASH_FCIM_EMASK;
1039
1040 //
1041 // Disable interrupts from the EEPROM module.
1042 //
1043 HWREG(EEPROM_EEINT) &= ~EEPROM_EEINT_INT;
1044 }
1045
1046 //*****************************************************************************
1047 //
1048 //! Reports the state of the EEPROM interrupt.
1049 //!
1050 //! \param bMasked determines whether the masked or unmasked state of the
1051 //! interrupt is to be returned. If bMasked is \b true, the masked state is
1052 //! returned, otherwise the unmasked state is returned.
1053 //!
1054 //! This function allows an application to query the state of the EEPROM
1055 //! interrupt. If active, the interrupt may be cleared by calling
1056 //! EEPROMIntClear().
1057 //!
1058 //! \return Returns \b EEPROM_INT_PROGRAM if an interrupt is being signaled or
1059 //! 0 otherwise.
1060 //
1061 //*****************************************************************************
1062 uint32_t
EEPROMIntStatus(bool bMasked)1063 EEPROMIntStatus(bool bMasked)
1064 {
1065 if(bMasked)
1066 {
1067 //
1068 // If asked for the masked interrupt status, we check to see if the
1069 // relevant interrupt is pending in the flash controller then return
1070 // the appropriate EEPROM flag if it is.
1071 //
1072 return((HWREG(FLASH_FCMISC) & FLASH_FCMISC_EMISC) ?
1073 EEPROM_INT_PROGRAM : 0);
1074 }
1075 else
1076 {
1077 //
1078 // If asked for the unmasked interrupt status, infer that an interrupt
1079 // is pending if the WORKING bit of the EEDONE register is clear. The
1080 // actual interrupt fires on the high to low transition of this bit
1081 // but we don't have access to an unmasked interrupt status for the
1082 // EEPROM because it's handled via the flash controller so we have to
1083 // make do with this instead.
1084 //
1085 return((HWREG(EEPROM_EEDONE) & EEPROM_EEDONE_WORKING) ?
1086 0 : EEPROM_INT_PROGRAM);
1087 }
1088 }
1089
1090 //*****************************************************************************
1091 //
1092 //! Clears the EEPROM interrupt.
1093 //!
1094 //! \param ui32IntFlags indicates which interrupt sources to clear. Currently,
1095 //! the only valid value is \b EEPROM_INT_PROGRAM.
1096 //!
1097 //! This function allows an application to clear the EEPROM interrupt.
1098 //!
1099 //! \note Because there is a write buffer in the Cortex-M processor, it may
1100 //! take several clock cycles before the interrupt source is actually cleared.
1101 //! Therefore, it is recommended that the interrupt source be cleared early in
1102 //! the interrupt handler (as opposed to the very last action) to avoid
1103 //! returning from the interrupt handler before the interrupt source is
1104 //! actually cleared. Failure to do so may result in the interrupt handler
1105 //! being immediately reentered (because the interrupt controller still sees
1106 //! the interrupt source asserted).
1107 //!
1108 //! \return None.
1109 //!
1110 //*****************************************************************************
1111 void
EEPROMIntClear(uint32_t ui32IntFlags)1112 EEPROMIntClear(uint32_t ui32IntFlags)
1113 {
1114 //
1115 // Clear the flash interrupt.
1116 //
1117 HWREG(FLASH_FCMISC) = FLASH_FCMISC_EMISC;
1118
1119 //
1120 // Clear the sector protection bits to prevent possible problems when
1121 // programming the main flash array later.
1122 //
1123 if(CLASS_IS_TM4C123 && REVISION_IS_A0)
1124 {
1125 _EEPROMSectorMaskClear();
1126 }
1127 }
1128
1129 //*****************************************************************************
1130 //
1131 //! Returns status on the last EEPROM program or erase operation.
1132 //!
1133 //! This function returns the current status of the last program or erase
1134 //! operation performed by the EEPROM. It is intended to provide error
1135 //! information to applications programming or setting EEPROM protection
1136 //! options under interrupt control.
1137 //!
1138 //! \return Returns 0 if the last program or erase operation completed without
1139 //! any errors. If an operation is ongoing or an error occurred, the return
1140 //! value is a logical OR combination of \b EEPROM_RC_WRBUSY, \b
1141 //! EEPROM_RC_NOPERM, \b EEPROM_RC_WKCOPY, \b EEPROM_RC_WKERASE, and \b
1142 //! EEPROM_RC_WORKING.
1143 //!
1144 //*****************************************************************************
1145 uint32_t
EEPROMStatusGet(void)1146 EEPROMStatusGet(void)
1147 {
1148 return(HWREG(EEPROM_EEDONE));
1149 }
1150
1151 //*****************************************************************************
1152 //
1153 // Close the Doxygen group.
1154 //! @}
1155 //
1156 //*****************************************************************************
1157