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