EFM32 Leopard Gecko Software Documentation  efm32lg-doc-4.2.1
em_msc.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_msc.h"
34 #if defined( MSC_COUNT ) && ( MSC_COUNT > 0 )
35 
36 #include "em_system.h"
37 #include "em_int.h"
38 #if defined( _MSC_TIMEBASE_MASK )
39 #include "em_cmu.h"
40 #endif
41 #include "em_assert.h"
42 
45 #if defined( MSC_WRITECTRL_WDOUBLE )
46 #define WORDS_PER_DATA_PHASE (FLASH_SIZE < (512 * 1024) ? 1 : 2)
47 #else
48 #define WORDS_PER_DATA_PHASE (1)
49 #endif
50 
51 typedef enum {
52  mscWriteIntSafe,
53  mscWriteFast,
54 } MSC_WriteStrategy_Typedef;
55 
56 MSC_FUNC_PREFIX static MSC_Status_TypeDef
57  MSC_WriteWordI(uint32_t *address,
58  void const *data,
59  uint32_t numBytes,
60  MSC_WriteStrategy_Typedef writeStrategy) MSC_FUNC_POSTFIX;
61 
62 MSC_FUNC_PREFIX __STATIC_INLINE MSC_Status_TypeDef
63  MSC_LoadWriteData(uint32_t* data,
64  uint32_t numWords,
65  MSC_WriteStrategy_Typedef writeStrategy) MSC_FUNC_POSTFIX;
66 
67 MSC_FUNC_PREFIX __STATIC_INLINE MSC_Status_TypeDef
68  MSC_LoadVerifyAddress(uint32_t* address) MSC_FUNC_POSTFIX;
69 
72 /***************************************************************************/
77 /***************************************************************************/
83 /*******************************************************************************
84  ************************** GLOBAL FUNCTIONS *******************************
85  ******************************************************************************/
86 
87 /***************************************************************************/
101 void MSC_Init(void)
102 {
103 #if defined( _MSC_TIMEBASE_MASK )
104  uint32_t freq, cycles;
105 #endif
106  /* Unlock the MSC */
107  MSC->LOCK = MSC_UNLOCK_CODE;
108  /* Disable writing to the flash */
109  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
110 
111  /* Call SystemCoreClockGet in order to set the global variable SystemCoreClock
112  which is used in MSC_LoadWriteData to make sure the frequency is
113  sufficiently high. If the clock frequency is changed then software is
114  responsible for calling MSC_Init or SystemCoreClockGet in order to set the
115  SystemCoreClock variable to the correct value. */
117 
118 #if defined( _MSC_TIMEBASE_MASK )
119  /* Configure MSC->TIMEBASE according to selected frequency */
121 
122  if (freq > 7000000)
123  {
124  /* Calculate number of clock cycles for 1us as base period */
125  freq = (freq * 11) / 10;
126  cycles = (freq / 1000000) + 1;
127 
128  /* Configure clock cycles for flash timing */
129  MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK
132  | (cycles << _MSC_TIMEBASE_BASE_SHIFT);
133  }
134  else
135  {
136  /* Calculate number of clock cycles for 5us as base period */
137  freq = (freq * 5 * 11) / 10;
138  cycles = (freq / 1000000) + 1;
139 
140  /* Configure clock cycles for flash timing */
141  MSC->TIMEBASE = (MSC->TIMEBASE & ~(_MSC_TIMEBASE_BASE_MASK
144  | (cycles << _MSC_TIMEBASE_BASE_SHIFT);
145  }
146 #endif
147 }
148 
149 /***************************************************************************/
153 void MSC_Deinit(void)
154 {
155  /* Disable writing to the flash */
156  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
157  /* Lock the MSC */
158  MSC->LOCK = 0;
159 }
160 
161 
162 #if !defined( _EFM32_GECKO_FAMILY )
163 /***************************************************************************/
171 {
172  uint32_t mscReadCtrl;
173 
174  mscReadCtrl = MSC->READCTRL & ~(0
175 #if defined( MSC_READCTRL_SCBTP )
176  | MSC_READCTRL_SCBTP
177 #endif
178 #if defined( MSC_READCTRL_USEHPROT )
179  | MSC_READCTRL_USEHPROT
180 #endif
181 #if defined( MSC_READCTRL_PREFETCH )
182  | MSC_READCTRL_PREFETCH
183 #endif
184 #if defined( MSC_READCTRL_ICCDIS )
186 #endif
187 #if defined( MSC_READCTRL_AIDIS )
189 #endif
190 #if defined( MSC_READCTRL_IFCDIS )
192 #endif
193  );
194  mscReadCtrl |= (0
195 #if defined( MSC_READCTRL_SCBTP )
196  | (execConfig->scbtEn ? MSC_READCTRL_SCBTP : 0)
197 #endif
198 #if defined( MSC_READCTRL_USEHPROT )
199  | (execConfig->useHprot ? MSC_READCTRL_USEHPROT : 0)
200 #endif
201 #if defined( MSC_READCTRL_PREFETCH )
202  | (execConfig->prefetchEn ? MSC_READCTRL_PREFETCH : 0)
203 #endif
204 #if defined( MSC_READCTRL_ICCDIS )
205  | (execConfig->iccDis ? MSC_READCTRL_ICCDIS : 0)
206 #endif
207 #if defined( MSC_READCTRL_AIDIS )
208  | (execConfig->aiDis ? MSC_READCTRL_AIDIS : 0)
209 #endif
210 #if defined( MSC_READCTRL_IFCDIS )
211  | (execConfig->ifcDis ? MSC_READCTRL_IFCDIS : 0)
212 #endif
213  );
214  MSC->READCTRL = mscReadCtrl;
215 }
216 #endif
217 
220 /***************************************************************************/
237 #if !defined(EM_MSC_RUN_FROM_FLASH)
238 #if defined(__CC_ARM) /* MDK-ARM compiler */
239 #pragma arm section code="ram_code"
240 #elif defined(__ICCARM__)
241 /* Suppress warnings originating from use of EFM_ASSERT(): */
242 /* "Call to a non __ramfunc function from within a __ramfunc function" */
243 /* "Possible rom access from within a __ramfunc function" */
244 #pragma diag_suppress=Ta022
245 #pragma diag_suppress=Ta023
246 __ramfunc
247 #endif
248 #endif /* !EM_MSC_RUN_FROM_FLASH */
249 __STATIC_INLINE MSC_Status_TypeDef MSC_LoadVerifyAddress(uint32_t* address)
250 {
251  uint32_t status;
252  uint32_t timeOut;
253 
254  /* Wait for the MSC to become ready. */
255  timeOut = MSC_PROGRAM_TIMEOUT;
256  while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
257  {
258  timeOut--;
259  }
260 
261  /* Check for timeout */
262  if (timeOut == 0)
263  {
264  return mscReturnTimeOut;
265  }
266  /* Load address */
267  MSC->ADDRB = (uint32_t)address;
268  MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
269 
270  status = MSC->STATUS;
271  if (status & (MSC_STATUS_INVADDR | MSC_STATUS_LOCKED))
272  {
273  /* Check for invalid address */
274  if (status & MSC_STATUS_INVADDR)
275  return mscReturnInvalidAddr;
276  /* Check for write protected page */
277  if (status & MSC_STATUS_LOCKED)
278  return mscReturnLocked;
279  }
280  return mscReturnOk;
281 }
282 #if defined(__ICCARM__)
283 #pragma diag_default=Ta022
284 #pragma diag_default=Ta023
285 #elif defined(__CC_ARM) /* MDK-ARM compiler */
286 #pragma arm section code
287 #endif /* __CC_ARM */
288 
289 
290 /***************************************************************************/
310 #if !defined(EM_MSC_RUN_FROM_FLASH)
311 #if defined(__CC_ARM) /* MDK-ARM compiler */
312 #pragma arm section code="ram_code"
313 #elif defined(__ICCARM__)
314 /* Suppress warnings originating from use of EFM_ASSERT(): */
315 /* "Call to a non __ramfunc function from within a __ramfunc function" */
316 /* "Possible rom access from within a __ramfunc function" */
317 #pragma diag_suppress=Ta022
318 #pragma diag_suppress=Ta023
319 __ramfunc
320 #endif
321 #endif /* !EM_MSC_RUN_FROM_FLASH */
322 __STATIC_INLINE MSC_Status_TypeDef
323  MSC_LoadWriteData(uint32_t* data,
324  uint32_t numWords,
325  MSC_WriteStrategy_Typedef writeStrategy)
326 {
327  uint32_t timeOut;
328  uint32_t wordIndex;
329  uint32_t wordsPerDataPhase;
331 
332 #if defined(_MSC_WRITECTRL_LPWRITE_MASK) && defined(_MSC_WRITECTRL_WDOUBLE_MASK)
333  /* If LPWRITE (Low Power Write) is NOT enabled, set WDOUBLE (Write Double word) */
334  if (!(MSC->WRITECTRL & MSC_WRITECTRL_LPWRITE))
335  {
336  /* If the number of words to be written are odd, we need to align by writing
337  a single word first, before setting the WDOUBLE bit. */
338  if (numWords & 0x1)
339  {
340  /* Wait for the MSC to become ready for the next word. */
341  timeOut = MSC_PROGRAM_TIMEOUT;
342  while ((!(MSC->STATUS & MSC_STATUS_WDATAREADY)) && (timeOut != 0))
343  {
344  timeOut--;
345  }
346  /* Check for timeout */
347  if (timeOut == 0)
348  {
349  return mscReturnTimeOut;
350  }
351  /* Clear double word option, in order to write the initial single word. */
352  MSC->WRITECTRL &= ~MSC_WRITECTRL_WDOUBLE;
353  /* Write first data word. */
354  MSC->WDATA = *data++;
355  MSC->WRITECMD = MSC_WRITECMD_WRITEONCE;
356 
357  /* Wait for the operation to finish. It may be required to change the WDOUBLE
358  config after the initial write. It should not be changed while BUSY. */
359  timeOut = MSC_PROGRAM_TIMEOUT;
360  while((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
361  {
362  timeOut--;
363  }
364  /* Check for timeout */
365  if (timeOut == 0)
366  {
367  return mscReturnTimeOut;
368  }
369  /* Subtract this initial odd word for the write loop below */
370  numWords -= 1;
371  retval = mscReturnOk;
372  }
373  /* Now we can set the double word option in order to write two words per
374  data phase. */
375  MSC->WRITECTRL |= MSC_WRITECTRL_WDOUBLE;
376  wordsPerDataPhase = 2;
377  }
378  else
379 #endif /* defined( _MSC_WRITECTRL_LPWRITE_MASK ) && defined( _MSC_WRITECTRL_WDOUBLE_MASK ) */
380  {
381  wordsPerDataPhase = 1;
382  }
383 
384  /* Write the rest as double word write if wordsPerDataPhase == 2 */
385  if (numWords > 0)
386  {
387  /**** Write strategy: mscWriteIntSafe ****/
388  if (writeStrategy == mscWriteIntSafe)
389  {
390  /* Requires a system core clock at 1MHz or higher */
391  EFM_ASSERT(SystemCoreClockGet() >= 1000000);
392  wordIndex = 0;
393  while(wordIndex < numWords)
394  {
395  MSC->WDATA = *data++;
396  wordIndex++;
397  if (wordsPerDataPhase == 2)
398  {
399  while (!(MSC->STATUS & MSC_STATUS_WDATAREADY));
400  MSC->WDATA = *data++;
401  wordIndex++;
402  }
403  MSC->WRITECMD = MSC_WRITECMD_WRITEONCE;
404 
405  /* Wait for the transaction to finish. */
406  timeOut = MSC_PROGRAM_TIMEOUT;
407  while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
408  {
409  timeOut--;
410  }
411  /* Check for timeout */
412  if (timeOut == 0)
413  {
414  retval = mscReturnTimeOut;
415  break;
416  }
417 #if defined( _EFM32_GECKO_FAMILY )
418  MSC->ADDRB += 4;
419  MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
420 #endif
421  }
422  }
423 
424  /**** Write strategy: mscWriteFast ****/
425  else
426  {
427 #if defined( _EFM32_GECKO_FAMILY )
428  /* Gecko does not have auto-increment of ADDR. */
429  EFM_ASSERT(0);
430 #else
431  /* Requires a system core clock at 14MHz or higher */
432  EFM_ASSERT(SystemCoreClockGet() >= 14000000);
433 
434  wordIndex = 0;
435  INT_Disable();
436  while(wordIndex < numWords)
437  {
438  /* Wait for the MSC to be ready for the next word. */
439  while (!(MSC->STATUS & MSC_STATUS_WDATAREADY))
440  {
441  /* If the write to MSC->WDATA below missed the 30us timeout and the
442  following MSC_WRITECMD_WRITETRIG command arrived while
443  MSC_STATUS_BUSY is 1, then the MSC_WRITECMD_WRITETRIG could be ignored by
444  the MSC. In this case, MSC_STATUS_WORDTIMEOUT is set to 1
445  and MSC_STATUS_BUSY is 0. A new trigger is therefore needed here to
446  complete write of data in MSC->WDATA.
447  If WDATAREADY became high since entry into this loop, exit and continue
448  to the next WDATA write.
449  */
450  if ((MSC->STATUS & (MSC_STATUS_WORDTIMEOUT
454  {
455  MSC->WRITECMD = MSC_WRITECMD_WRITETRIG;
456  }
457  }
458  MSC->WDATA = *data;
459  if ((wordsPerDataPhase == 1)
460  || ((wordsPerDataPhase == 2) && (wordIndex & 0x1)))
461  {
462  MSC->WRITECMD = MSC_WRITECMD_WRITETRIG;
463  }
464  data++;
465  wordIndex++;
466  }
467  INT_Enable();
468 
469  /* Wait for the transaction to finish. */
470  timeOut = MSC_PROGRAM_TIMEOUT;
471  while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
472  {
473  timeOut--;
474  }
475  /* Check for timeout */
476  if (timeOut == 0)
477  {
478  retval = mscReturnTimeOut;
479  }
480 #endif
481  } /* writeStrategy */
482  }
483 
484 #if defined( _MSC_WRITECTRL_WDOUBLE_MASK )
485  /* Clear double word option, which should not be left on when returning. */
486  MSC->WRITECTRL &= ~MSC_WRITECTRL_WDOUBLE;
487 #endif
488 
489  return retval;
490 }
491 #if defined(__ICCARM__)
492 #pragma diag_default=Ta022
493 #pragma diag_default=Ta023
494 #elif defined(__CC_ARM) /* MDK-ARM compiler */
495 #pragma arm section code
496 #endif /* __CC_ARM */
497 
498 
499 /***************************************************************************/
513 #if !defined(EM_MSC_RUN_FROM_FLASH)
514 #if defined(__CC_ARM) /* MDK-ARM compiler */
515 #pragma arm section code="ram_code"
516 #elif defined(__ICCARM__)
517 /* Suppress warnings originating from use of EFM_ASSERT(): */
518 /* "Call to a non __ramfunc function from within a __ramfunc function" */
519 /* "Possible rom access from within a __ramfunc function" */
520 #pragma diag_suppress=Ta022
521 #pragma diag_suppress=Ta023
522 #endif
523 #endif /* !EM_MSC_RUN_FROM_FLASH */
524 static MSC_Status_TypeDef MSC_WriteWordI(uint32_t *address,
525  void const *data,
526  uint32_t numBytes,
527  MSC_WriteStrategy_Typedef writeStrategy)
528 {
529  uint32_t wordCount;
530  uint32_t numWords;
531  uint32_t pageWords;
532  uint32_t* pData;
534 
535  /* Check alignment (Must be aligned to words) */
536  EFM_ASSERT(((uint32_t) address & 0x3) == 0);
537 
538  /* Check number of bytes. Must be divisable by four */
539  EFM_ASSERT((numBytes & 0x3) == 0);
540 
541  /* Enable writing to the MSC */
542  MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
543 
544  /* Convert bytes to words */
545  numWords = numBytes >> 2;
546  EFM_ASSERT(numWords > 0);
547 
548  /* The following loop splits the data into chunks corresponding to flash pages.
549  The address is loaded only once per page, because the hardware automatically
550  increments the address internally for each data load inside a page. */
551  for (wordCount = 0, pData = (uint32_t *)data; wordCount < numWords; )
552  {
553  /* First we load address. The address is auto-incremented within a page.
554  Therefore the address phase is only needed once for each page. */
555  retval = MSC_LoadVerifyAddress(address + wordCount);
556  if (mscReturnOk != retval)
557  {
558  return retval;
559  }
560  /* Compute the number of words to write to the current page. */
561  pageWords =
562  (FLASH_PAGE_SIZE -
563  (((uint32_t) (address + wordCount)) & (FLASH_PAGE_SIZE - 1)))
564  / sizeof(uint32_t);
565  if (pageWords > numWords - wordCount)
566  {
567  pageWords = numWords - wordCount;
568  }
569  /* Now write the data in the current page. */
570  retval = MSC_LoadWriteData(pData, pageWords, writeStrategy);
571  if (mscReturnOk != retval)
572  {
573  break;
574  }
575  wordCount += pageWords;
576  pData += pageWords;
577  }
578 
579  /* Disable writing to the MSC */
580  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
581 
582 #if defined( _MSC_WRITECTRL_WDOUBLE_MASK )
583 #if ( WORDS_PER_DATA_PHASE == 2 )
584  /* Turn off double word write cycle support. */
585  MSC->WRITECTRL &= ~MSC_WRITECTRL_WDOUBLE;
586 #endif
587 #endif
588 
589  return retval;
590 }
591 #if defined(__ICCARM__)
592 #pragma diag_default=Ta022
593 #pragma diag_default=Ta023
594 #elif defined(__CC_ARM) /* MDK-ARM compiler */
595 #pragma arm section code
596 #endif /* __CC_ARM */
597 
601 /***************************************************************************/
626 #if !defined(EM_MSC_RUN_FROM_FLASH)
627 #if defined(__CC_ARM) /* MDK-ARM compiler */
628 #pragma arm section code="ram_code"
629 #elif defined(__ICCARM__)
630 /* Suppress warnings originating from use of EFM_ASSERT(): */
631 /* "Call to a non __ramfunc function from within a __ramfunc function" */
632 /* "Possible rom access from within a __ramfunc function" */
633 #pragma diag_suppress=Ta022
634 #pragma diag_suppress=Ta023
635 #endif
636 #endif /* !EM_MSC_RUN_FROM_FLASH */
637 MSC_Status_TypeDef MSC_ErasePage(uint32_t *startAddress)
638 {
639  uint32_t timeOut = MSC_PROGRAM_TIMEOUT;
640 
641  /* Address must be aligned to pages */
642  EFM_ASSERT((((uint32_t) startAddress) & (FLASH_PAGE_SIZE - 1)) == 0);
643 
644  /* Enable writing to the MSC */
645  MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
646 
647  /* Load address */
648  MSC->ADDRB = (uint32_t)startAddress;
649  MSC->WRITECMD = MSC_WRITECMD_LADDRIM;
650 
651  /* Check for invalid address */
652  if (MSC->STATUS & MSC_STATUS_INVADDR)
653  {
654  /* Disable writing to the MSC */
655  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
656  return mscReturnInvalidAddr;
657  }
658  /* Check for write protected page */
659  if (MSC->STATUS & MSC_STATUS_LOCKED)
660  {
661  /* Disable writing to the MSC */
662  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
663  return mscReturnLocked;
664  }
665  /* Send erase page command */
666  MSC->WRITECMD = MSC_WRITECMD_ERASEPAGE;
667 
668  /* Wait for the erase to complete */
669  while ((MSC->STATUS & MSC_STATUS_BUSY) && (timeOut != 0))
670  {
671  timeOut--;
672  }
673  if (timeOut == 0)
674  {
675  /* Disable writing to the MSC */
676  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
677  return mscReturnTimeOut;
678  }
679  /* Disable writing to the MSC */
680  MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN;
681  return mscReturnOk;
682 }
683 #if defined(__ICCARM__)
684 #pragma diag_default=Ta022
685 #pragma diag_default=Ta023
686 #elif defined(__CC_ARM) /* MDK-ARM compiler */
687 #pragma arm section code
688 #endif /* __CC_ARM */
689 
690 
691 /***************************************************************************/
727 #if !defined(EM_MSC_RUN_FROM_FLASH)
728 #if defined(__CC_ARM) /* MDK-ARM compiler */
729 #pragma arm section code="ram_code"
730 #elif defined(__ICCARM__)
731 /* Suppress warnings originating from use of EFM_ASSERT(): */
732 /* "Call to a non __ramfunc function from within a __ramfunc function" */
733 /* "Possible rom access from within a __ramfunc function" */
734 #pragma diag_suppress=Ta022
735 #pragma diag_suppress=Ta023
736 #endif
737 #endif /* !EM_MSC_RUN_FROM_FLASH */
739  void const *data,
740  uint32_t numBytes)
741 {
742  return MSC_WriteWordI(address, data, numBytes, mscWriteIntSafe);
743 }
744 #if defined(__ICCARM__)
745 #pragma diag_default=Ta022
746 #pragma diag_default=Ta023
747 #elif defined(__CC_ARM) /* MDK-ARM compiler */
748 #pragma arm section code
749 #endif /* __CC_ARM */
750 
751 
752 #if !defined( _EFM32_GECKO_FAMILY )
753 /***************************************************************************/
786 #if !defined(EM_MSC_RUN_FROM_FLASH)
787 #if defined(__CC_ARM) /* MDK-ARM compiler */
788 #pragma arm section code="ram_code"
789 #elif defined(__ICCARM__)
790 /* Suppress warnings originating from use of EFM_ASSERT(): */
791 /* "Call to a non __ramfunc function from within a __ramfunc function" */
792 /* "Possible rom access from within a __ramfunc function" */
793 #pragma diag_suppress=Ta022
794 #pragma diag_suppress=Ta023
795 #endif
796 #endif /* !EM_MSC_RUN_FROM_FLASH */
798  void const *data,
799  uint32_t numBytes)
800 {
801  return MSC_WriteWordI(address, data, numBytes, mscWriteFast);
802 }
803 #if defined(__ICCARM__)
804 #pragma diag_default=Ta022
805 #pragma diag_default=Ta023
806 #elif defined(__CC_ARM) /* MDK-ARM compiler */
807 #pragma arm section code
808 #endif /* __CC_ARM */
809 #endif
810 
811 
812 #if defined( _MSC_MASSLOCK_MASK )
813 /***************************************************************************/
822 #if !defined(EM_MSC_RUN_FROM_FLASH)
823 #if defined(__CC_ARM) /* MDK-ARM compiler */
824 #pragma arm section code="ram_code"
825 #endif /* __CC_ARM */
826 #endif /* !EM_MSC_RUN_FROM_FLASH */
828 {
829  /* Enable writing to the MSC */
830  MSC->WRITECTRL |= MSC_WRITECTRL_WREN;
831 
832  /* Unlock device mass erase */
833  MSC->MASSLOCK = MSC_MASSLOCK_LOCKKEY_UNLOCK;
834 
835  /* Erase first 512K block */
836  MSC->WRITECMD = MSC_WRITECMD_ERASEMAIN0;
837 
838  /* Waiting for erase to complete */
839  while ((MSC->STATUS & MSC_STATUS_BUSY));
840 
841 #if ((FLASH_SIZE >= (512 * 1024)) && defined( _MSC_WRITECMD_ERASEMAIN1_MASK ))
842  /* Erase second 512K block */
843  MSC->WRITECMD = MSC_WRITECMD_ERASEMAIN1;
844 
845  /* Waiting for erase to complete */
846  while ((MSC->STATUS & MSC_STATUS_BUSY));
847 #endif
848 
849  /* Restore mass erase lock */
850  MSC->MASSLOCK = MSC_MASSLOCK_LOCKKEY_LOCK;
851 
852  /* This will only successfully return if calling function is also in SRAM */
853  return mscReturnOk;
854 }
855 #if defined(__CC_ARM) /* MDK-ARM compiler */
856 #pragma arm section code
857 #endif /* __CC_ARM */
858 #endif
859 
862 #endif /* defined(MSC_COUNT) && (MSC_COUNT > 0) */
Clock management unit (CMU) API.
uint32_t SystemCoreClockGet(void)
Get the current core clock frequency.
#define MSC_WRITECMD_ERASEMAIN0
Definition: efm32lg_msc.h:189
Emlib peripheral API "assert" implementation.
#define MSC_STATUS_WDATAREADY
Definition: efm32lg_msc.h:234
#define MSC_WRITECTRL_WREN
Definition: efm32lg_msc.h:145
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
Definition: em_int.h:94
#define MSC_READCTRL_ICCDIS
Definition: efm32lg_msc.h:114
#define MSC_STATUS_INVADDR
Definition: efm32lg_msc.h:229
void MSC_Init(void)
Enables the flash controller for writing.
Definition: em_msc.c:101
void MSC_Deinit(void)
Disables the flash controller for writing.
Definition: em_msc.c:153
MSC_FUNC_PREFIX MSC_Status_TypeDef MSC_WriteWordFast(uint32_t *address, void const *data, uint32_t numBytes) MSC_FUNC_POSTFIX
Writes data to flash memory. This function is faster than MSC_WriteWord(), but it disables interrupts...
Definition: em_msc.c:797
#define MSC_UNLOCK_CODE
#define FLASH_PAGE_SIZE
#define MSC_PROGRAM_TIMEOUT
The timeout used while waiting for the flash to become ready after a write. This number indicates the...
Definition: em_msc.h:72
void MSC_ExecConfigSet(MSC_ExecConfig_TypeDef *execConfig)
Set MSC code execution configuration.
Definition: em_msc.c:170
#define MSC_TIMEBASE_PERIOD_1US
Definition: efm32lg_msc.h:416
Flash controller module (MSC) peripheral API.
Interrupt enable/disable unit API.
#define MSC_READCTRL_AIDIS
Definition: efm32lg_msc.h:109
#define MSC_MASSLOCK_LOCKKEY_UNLOCK
Definition: efm32lg_msc.h:433
#define MSC_WRITECMD_ERASEPAGE
Definition: efm32lg_msc.h:164
#define MSC
#define MSC_STATUS_WORDTIMEOUT
Definition: efm32lg_msc.h:239
#define _MSC_TIMEBASE_BASE_MASK
Definition: efm32lg_msc.h:406
MSC_FUNC_PREFIX MSC_Status_TypeDef MSC_ErasePage(uint32_t *startAddress) MSC_FUNC_POSTFIX
Erases a page in flash memory.
Definition: em_msc.c:637
#define MSC_WRITECMD_WRITETRIG
Definition: efm32lg_msc.h:179
#define MSC_WRITECMD_LADDRIM
Definition: efm32lg_msc.h:159
MSC_FUNC_PREFIX MSC_Status_TypeDef MSC_MassErase(void) MSC_FUNC_POSTFIX
Erase entire flash in one operation.
Definition: em_msc.c:827
#define MSC_STATUS_BUSY
Definition: efm32lg_msc.h:219
MSC_Status_TypeDef
Definition: em_msc.h:97
#define MSC_WRITECMD_WRITEONCE
Definition: efm32lg_msc.h:174
System API.
#define MSC_TIMEBASE_PERIOD_5US
Definition: efm32lg_msc.h:417
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
Definition: em_int.h:71
#define _MSC_TIMEBASE_PERIOD_MASK
Definition: efm32lg_msc.h:411
#define _MSC_TIMEBASE_BASE_SHIFT
Definition: efm32lg_msc.h:405
MSC_FUNC_PREFIX MSC_Status_TypeDef MSC_WriteWord(uint32_t *address, void const *data, uint32_t numBytes) MSC_FUNC_POSTFIX
Writes data to flash memory. This function is interrupt safe, but slower than MSC_WriteWordFast(), which writes to flash with interrupts disabled. Write data must be aligned to words and contain a number of bytes that is divisable by four.
Definition: em_msc.c:738
#define MSC_MASSLOCK_LOCKKEY_LOCK
Definition: efm32lg_msc.h:429
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
Definition: em_cmu.c:1482
#define MSC_STATUS_LOCKED
Definition: efm32lg_msc.h:224
#define MSC_READCTRL_IFCDIS
Definition: efm32lg_msc.h:104