EE445M RTOS
Taken at the University of Texas Spring 2015
flash.c
Go to the documentation of this file.
1 //*****************************************************************************
2 //
3 // flash.c - Driver for programming the on-chip flash.
4 //
5 // Copyright (c) 2005-2014 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.1.0.12573 of the Tiva Peripheral Driver Library.
37 //
38 //*****************************************************************************
39 
40 //*****************************************************************************
41 //
44 //
45 //*****************************************************************************
46 
47 #include <stdbool.h>
48 #include <stdint.h>
49 #include "inc/hw_flash.h"
50 #include "inc/hw_ints.h"
51 #include "inc/hw_sysctl.h"
52 #include "inc/hw_types.h"
53 #include "driverlib/debug.h"
54 #include "driverlib/flash.h"
55 #include "driverlib/interrupt.h"
56 
57 //*****************************************************************************
58 //
59 // An array that maps the specified memory bank to the appropriate Flash
60 // Memory Protection Program Enable (FMPPE) register.
61 //
62 //*****************************************************************************
63 static const uint32_t g_pui32FMPPERegs[] =
64 {
81 };
82 
83 //*****************************************************************************
84 //
85 // An array that maps the specified memory bank to the appropriate Flash
86 // Memory Protection Read Enable (FMPRE) register.
87 //
88 //*****************************************************************************
89 static const uint32_t g_pui32FMPRERegs[] =
90 {
100  FLASH_FMPRE9,
107 };
108 
109 //*****************************************************************************
110 //
127 //
128 //*****************************************************************************
129 int32_t
130 FlashErase(uint32_t ui32Address)
131 {
132  //
133  // Check the arguments.
134  //
135  ASSERT(!(ui32Address & (FLASH_ERASE_SIZE - 1)));
136 
137  //
138  // Clear the flash access and error interrupts.
139  //
142 
143  //
144  // Erase the block.
145  //
146  HWREG(FLASH_FMA) = ui32Address;
148 
149  //
150  // Wait until the block has been erased.
151  //
153  {
154  }
155 
156  //
157  // Return an error if an access violation or erase error occurred.
158  //
161  {
162  return(-1);
163  }
164 
165  //
166  // Success.
167  //
168  return(0);
169 }
170 
171 //*****************************************************************************
172 //
189 //
190 //*****************************************************************************
191 int32_t
192 FlashProgram(uint32_t *pui32Data, uint32_t ui32Address, uint32_t ui32Count)
193 {
194  //
195  // Check the arguments.
196  //
197  ASSERT(!(ui32Address & 3));
198  ASSERT(!(ui32Count & 3));
199 
200  //
201  // Clear the flash access and error interrupts.
202  //
205 
206  //
207  // Loop over the words to be programmed.
208  //
209  while(ui32Count)
210  {
211  //
212  // Set the address of this block of words.
213  //
214  HWREG(FLASH_FMA) = ui32Address & ~(0x7f);
215 
216  //
217  // Loop over the words in this 32-word block.
218  //
219  while(((ui32Address & 0x7c) || (HWREG(FLASH_FWBVAL) == 0)) &&
220  (ui32Count != 0))
221  {
222  //
223  // Write this word into the write buffer.
224  //
225  HWREG(FLASH_FWBN + (ui32Address & 0x7c)) = *pui32Data++;
226  ui32Address += 4;
227  ui32Count -= 4;
228  }
229 
230  //
231  // Program the contents of the write buffer into flash.
232  //
234 
235  //
236  // Wait until the write buffer has been programmed.
237  //
239  {
240  }
241  }
242 
243  //
244  // Return an error if an access violation occurred.
245  //
248  {
249  return(-1);
250  }
251 
252  //
253  // Success.
254  //
255  return(0);
256 }
257 
258 //*****************************************************************************
259 //
273 //
274 //*****************************************************************************
276 FlashProtectGet(uint32_t ui32Address)
277 {
278  uint32_t ui32FMPRE, ui32FMPPE;
279  uint32_t ui32Bank;
280 
281  //
282  // Check the argument.
283  //
284  ASSERT(!(ui32Address & (FLASH_PROTECT_SIZE - 1)));
285 
286  //
287  // Calculate the Flash Bank from Base Address, and mask off the Bank
288  // from ui32Address for subsequent reference.
289  //
290  ui32Bank = (((ui32Address / FLASH_PROTECT_SIZE) / 32) % 4);
291  ui32Address &= ((FLASH_PROTECT_SIZE * 32) - 1);
292 
293  //
294  // Read the appropriate flash protection registers for the specified
295  // flash bank.
296  //
297  ui32FMPRE = HWREG(g_pui32FMPRERegs[ui32Bank]);
298  ui32FMPPE = HWREG(g_pui32FMPPERegs[ui32Bank]);
299 
300  //
301  // Check the appropriate protection bits for the block of memory that
302  // is specified by the address.
303  //
304  switch((((ui32FMPRE >> (ui32Address / FLASH_PROTECT_SIZE)) & 0x1) << 1) |
305  ((ui32FMPPE >> (ui32Address / FLASH_PROTECT_SIZE)) & 0x1))
306  {
307  //
308  // This block is marked as execute only (that is, it can not be erased
309  // or programmed, and the only reads allowed are via the instruction
310  // fetch interface).
311  //
312  case 0:
313  case 1:
314  {
315  return(FlashExecuteOnly);
316  }
317 
318  //
319  // This block is marked as read only (that is, it can not be erased or
320  // programmed).
321  //
322  case 2:
323  {
324  return(FlashReadOnly);
325  }
326 
327  //
328  // This block is read/write; it can be read, erased, and programmed.
329  //
330  case 3:
331  default:
332  {
333  return(FlashReadWrite);
334  }
335  }
336 }
337 
338 //*****************************************************************************
339 //
362 //
363 //*****************************************************************************
364 int32_t
365 FlashProtectSet(uint32_t ui32Address, tFlashProtection eProtect)
366 {
367  uint32_t ui32ProtectRE, ui32ProtectPE;
368  uint32_t ui32Bank;
369 
370  //
371  // Check the argument.
372  //
373  ASSERT(!(ui32Address & (FLASH_PROTECT_SIZE - 1)));
374  ASSERT((eProtect == FlashReadWrite) || (eProtect == FlashReadOnly) ||
375  (eProtect == FlashExecuteOnly));
376 
377  //
378  // Convert the address into a block number.
379  //
380  ui32Address /= FLASH_PROTECT_SIZE;
381 
382  //
383  // ui32Address contains a "raw" block number. Derive the Flash Bank from
384  // the "raw" block number, and convert ui32Address to a "relative"
385  // block number.
386  //
387  ui32Bank = ((ui32Address / 32) % 4);
388  ui32Address %= 32;
389 
390  //
391  // Get the current protection for the specified flash bank.
392  //
393  ui32ProtectRE = HWREG(g_pui32FMPRERegs[ui32Bank]);
394  ui32ProtectPE = HWREG(g_pui32FMPPERegs[ui32Bank]);
395 
396  //
397  // Set the protection based on the requested protection.
398  //
399  switch(eProtect)
400  {
401  //
402  // Make this block execute only.
403  //
404  case FlashExecuteOnly:
405  {
406  //
407  // Turn off the read and program bits for this block.
408  //
409  ui32ProtectRE &= ~(0x1 << ui32Address);
410  ui32ProtectPE &= ~(0x1 << ui32Address);
411 
412  //
413  // We're done handling this protection.
414  //
415  break;
416  }
417 
418  //
419  // Make this block read only.
420  //
421  case FlashReadOnly:
422  {
423  //
424  // The block can not be made read only if it is execute only.
425  //
426  if(((ui32ProtectRE >> ui32Address) & 0x1) != 0x1)
427  {
428  return(-1);
429  }
430 
431  //
432  // Make this block read only.
433  //
434  ui32ProtectPE &= ~(0x1 << ui32Address);
435 
436  //
437  // We're done handling this protection.
438  //
439  break;
440  }
441 
442  //
443  // Make this block read/write.
444  //
445  case FlashReadWrite:
446  default:
447  {
448  //
449  // The block can not be made read/write if it is not already
450  // read/write.
451  //
452  if((((ui32ProtectRE >> ui32Address) & 0x1) != 0x1) ||
453  (((ui32ProtectPE >> ui32Address) & 0x1) != 0x1))
454  {
455  return(-1);
456  }
457 
458  //
459  // The block is already read/write, so there is nothing to do.
460  //
461  return(0);
462  }
463  }
464 
465  //
466  // Set the new protection for the specified flash bank.
467  //
468  HWREG(g_pui32FMPRERegs[ui32Bank]) = ui32ProtectRE;
469  HWREG(g_pui32FMPPERegs[ui32Bank]) = ui32ProtectPE;
470 
471  //
472  // Success.
473  //
474  return(0);
475 }
476 
477 //*****************************************************************************
478 //
488 //
489 //*****************************************************************************
490 int32_t
492 {
493  uint32_t ui32Temp;
494 
495  //
496  // Save the entire bank of 8 flash protection registers.
497  //
498  for(ui32Temp = 0; ui32Temp < 8; ui32Temp++)
499  {
500  //
501  // Tell the flash controller to write the flash protection register.
502  //
503  HWREG(FLASH_FMA) = ui32Temp;
505 
506  //
507  // Wait until the write has completed.
508  //
509  while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
510  {
511  }
512  }
513 
514  //
515  // Success.
516  //
517  return(0);
518 }
519 
520 //*****************************************************************************
521 //
531 //
532 //*****************************************************************************
533 int32_t
534 FlashUserGet(uint32_t *pui32User0, uint32_t *pui32User1)
535 {
536  //
537  // Verify that the pointers are valid.
538  //
539  ASSERT(pui32User0 != 0);
540  ASSERT(pui32User1 != 0);
541 
542  //
543  // Get and store the current value of the user registers.
544  //
545  *pui32User0 = HWREG(FLASH_USERREG0);
546  *pui32User1 = HWREG(FLASH_USERREG1);
547 
548  //
549  // Success.
550  //
551  return(0);
552 }
553 
554 //*****************************************************************************
555 //
565 //
566 //*****************************************************************************
567 int32_t
568 FlashUserSet(uint32_t ui32User0, uint32_t ui32User1)
569 {
570  //
571  // Save the new values into the user registers.
572  //
573  HWREG(FLASH_USERREG0) = ui32User0;
574  HWREG(FLASH_USERREG1) = ui32User1;
575 
576  //
577  // Success.
578  //
579  return(0);
580 }
581 
582 //*****************************************************************************
583 //
593 //
594 //*****************************************************************************
595 int32_t
597 {
598  //
599  // Setting the MSB of FMA will trigger a permanent save of a USER
600  // register. Bit 0 will indicate User 0 (0) or User 1 (1).
601  //
602  HWREG(FLASH_FMA) = 0x80000000;
604 
605  //
606  // Wait until the write has completed.
607  //
608  while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
609  {
610  }
611 
612  //
613  // Tell the flash controller to write the USER1 Register.
614  //
615  HWREG(FLASH_FMA) = 0x80000001;
617 
618  //
619  // Wait until the write has completed.
620  //
621  while(HWREG(FLASH_FMC) & FLASH_FMC_COMT)
622  {
623  }
624 
625  //
626  // Success.
627  //
628  return(0);
629 }
630 
631 //*****************************************************************************
632 //
649 //
650 //*****************************************************************************
651 void
652 FlashIntRegister(void (*pfnHandler)(void))
653 {
654  //
655  // Register the interrupt handler, returning an error if an error occurs.
656  //
657  IntRegister(INT_FLASH_TM4C123, pfnHandler);
658 
659  //
660  // Enable the flash interrupt.
661  //
663 }
664 
665 //*****************************************************************************
666 //
677 //
678 //*****************************************************************************
679 void
681 {
682  //
683  // Disable the interrupt.
684  //
686 
687  //
688  // Unregister the interrupt handler.
689  //
691 }
692 
693 //*****************************************************************************
694 //
718 //
719 //*****************************************************************************
720 void
721 FlashIntEnable(uint32_t ui32IntFlags)
722 {
723  //
724  // Enable the specified interrupts.
725  //
726  HWREG(FLASH_FCIM) |= ui32IntFlags;
727 }
728 
729 //*****************************************************************************
730 //
754 //
755 //*****************************************************************************
756 void
757 FlashIntDisable(uint32_t ui32IntFlags)
758 {
759  //
760  // Disable the specified interrupts.
761  //
762  HWREG(FLASH_FCIM) &= ~(ui32IntFlags);
763 }
764 
765 //*****************************************************************************
766 //
780 //
781 //*****************************************************************************
782 uint32_t
783 FlashIntStatus(bool bMasked)
784 {
785  //
786  // Return either the interrupt status or the raw interrupt status as
787  // requested.
788  //
789  if(bMasked)
790  {
791  return(HWREG(FLASH_FCMISC));
792  }
793  else
794  {
795  return(HWREG(FLASH_FCRIS));
796  }
797 }
798 
799 //*****************************************************************************
800 //
835 //
836 //*****************************************************************************
837 void
838 FlashIntClear(uint32_t ui32IntFlags)
839 {
840  //
841  // Clear the flash interrupt.
842  //
843  HWREG(FLASH_FCMISC) = ui32IntFlags;
844 }
845 
846 //*****************************************************************************
847 //
848 // Close the Doxygen group.
850 //
851 //*****************************************************************************
#define FLASH_FMPRE8
Definition: hw_flash.h:90
#define FLASH_FMPRE1
Definition: hw_flash.h:76
#define FLASH_FCMISC_INVDMISC
Definition: hw_flash.h:205
#define FLASH_FCMISC_VOLTMISC
Definition: hw_flash.h:207
#define FLASH_FMPPE9
Definition: hw_flash.h:124
int32_t FlashUserSave(void)
Definition: flash.c:596
#define FLASH_FCRIS_PROGRIS
Definition: hw_flash.h:171
#define HWREG(x)
Definition: hw_types.h:48
#define FLASH_PROTECT_SIZE
Definition: hw_flash.h:622
#define FLASH_FMPPE3
Definition: hw_flash.h:112
int32_t FlashErase(uint32_t ui32Address)
Definition: flash.c:130
#define FLASH_FMPPE11
Definition: hw_flash.h:128
#define FLASH_FMPPE0
Definition: hw_flash.h:106
#define FLASH_FCIM
Definition: hw_flash.h:53
#define FLASH_FCMISC_PROGMISC
Definition: hw_flash.h:201
#define FLASH_FMPPE10
Definition: hw_flash.h:126
#define FLASH_FMPRE4
Definition: hw_flash.h:82
#define FLASH_FMPPE5
Definition: hw_flash.h:116
#define ASSERT(expr)
Definition: debug.h:67
#define FLASH_FWBVAL
Definition: hw_flash.h:57
#define FLASH_USERREG0
Definition: hw_flash.h:70
#define FLASH_FMPRE9
Definition: hw_flash.h:92
#define FLASH_FCRIS_ERRIS
Definition: hw_flash.h:173
int32_t FlashProgram(uint32_t *pui32Data, uint32_t ui32Address, uint32_t ui32Count)
Definition: flash.c:192
static const uint32_t g_pui32FMPRERegs[]
Definition: flash.c:89
void FlashIntUnregister(void)
Definition: flash.c:680
tFlashProtection
Definition: flash.h:60
#define FLASH_FMPRE13
Definition: hw_flash.h:100
#define FLASH_FMPRE5
Definition: hw_flash.h:84
#define FLASH_FMPRE3
Definition: hw_flash.h:80
#define FLASH_FMPPE6
Definition: hw_flash.h:118
#define FLASH_FCRIS_ARIS
Definition: hw_flash.h:181
#define FLASH_FMPPE14
Definition: hw_flash.h:134
#define FLASH_FWBN
Definition: hw_flash.h:59
#define FLASH_FCRIS
Definition: hw_flash.h:51
void FlashIntRegister(void(*pfnHandler)(void))
Definition: flash.c:652
#define FLASH_FCRIS_VOLTRIS
Definition: hw_flash.h:177
#define FLASH_FMC2_WRBUF
Definition: hw_flash.h:222
#define FLASH_FMA
Definition: hw_flash.h:48
#define FLASH_FCMISC_ERMISC
Definition: hw_flash.h:203
int32_t FlashProtectSet(uint32_t ui32Address, tFlashProtection eProtect)
Definition: flash.c:365
#define FLASH_FCRIS_INVDRIS
Definition: hw_flash.h:175
#define FLASH_FCMISC_AMISC
Definition: hw_flash.h:213
#define FLASH_FMPPE1
Definition: hw_flash.h:108
#define INT_FLASH_TM4C123
Definition: hw_ints.h:93
#define FLASH_FMC2
Definition: hw_flash.h:56
static const uint32_t g_pui32FMPPERegs[]
Definition: flash.c:63
#define FLASH_FMPRE12
Definition: hw_flash.h:98
#define FLASH_FMC_WRKEY
Definition: hw_flash.h:160
#define FLASH_FMC_ERASE
Definition: hw_flash.h:163
void FlashIntDisable(uint32_t ui32IntFlags)
Definition: flash.c:757
#define FLASH_FMC
Definition: hw_flash.h:50
#define FLASH_FMPRE2
Definition: hw_flash.h:78
tFlashProtection FlashProtectGet(uint32_t ui32Address)
Definition: flash.c:276
#define FLASH_FMPRE7
Definition: hw_flash.h:88
#define FLASH_FMC_COMT
Definition: hw_flash.h:161
#define FLASH_FMPPE4
Definition: hw_flash.h:114
uint32_t FlashIntStatus(bool bMasked)
Definition: flash.c:783
#define FLASH_FMC2_WRKEY
Definition: hw_flash.h:221
void IntUnregister(uint32_t ui32Interrupt)
Definition: interrupt.c:381
#define FLASH_FMPPE12
Definition: hw_flash.h:130
void FlashIntClear(uint32_t ui32IntFlags)
Definition: flash.c:838
#define FLASH_FMPPE2
Definition: hw_flash.h:110
#define FLASH_FMPPE15
Definition: hw_flash.h:136
#define FLASH_FMPRE14
Definition: hw_flash.h:102
int32_t FlashUserGet(uint32_t *pui32User0, uint32_t *pui32User1)
Definition: flash.c:534
#define FLASH_FMPRE15
Definition: hw_flash.h:104
#define FLASH_FMPRE0
Definition: hw_flash.h:74
#define FLASH_FCMISC
Definition: hw_flash.h:54
void FlashIntEnable(uint32_t ui32IntFlags)
Definition: flash.c:721
int32_t FlashUserSet(uint32_t ui32User0, uint32_t ui32User1)
Definition: flash.c:568
#define FLASH_FMPPE7
Definition: hw_flash.h:120
#define FLASH_USERREG1
Definition: hw_flash.h:71
int32_t FlashProtectSave(void)
Definition: flash.c:491
#define FLASH_FMPRE11
Definition: hw_flash.h:96
#define FLASH_FMPRE6
Definition: hw_flash.h:86
#define FLASH_FMPRE10
Definition: hw_flash.h:94
void IntDisable(uint32_t ui32Interrupt)
Definition: interrupt.c:684
void IntRegister(uint32_t ui32Interrupt, void(*pfnHandler)(void))
Definition: interrupt.c:309
void IntEnable(uint32_t ui32Interrupt)
Definition: interrupt.c:610
#define FLASH_FMPPE8
Definition: hw_flash.h:122
#define FLASH_ERASE_SIZE
Definition: hw_flash.h:623
#define FLASH_FMPPE13
Definition: hw_flash.h:132