flash_efc.c
Go to the documentation of this file.
1 
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 
47 #include <string.h>
48 #include <assert.h>
49 #include "flash_efc.h"
50 #include "sysclk.h"
51 
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 
68 #if (SAM4E || SAM4N || SAM4S || SAM4C || SAMG || SAM4CP || SAM4CM || \
69  SAMV71 || SAMV70 || SAMS70 || SAME70)
70 /* User signature size */
71 # define FLASH_USER_SIG_SIZE (512)
72 #endif
73 
74 #if SAM4S
75 /* Internal Flash Controller 0. */
76 # define EFC EFC0
77 #if (SAM4SD16 || SAM4SD32)
78 /* The max GPNVM number. */
79 # define GPNVM_NUM_MAX 3
80 #else
81 /* The max GPNVM number. */
82 # define GPNVM_NUM_MAX 2
83 #endif
84 /* Internal Flash 0 base address. */
85 # define IFLASH_ADDR IFLASH0_ADDR
86 /* Internal flash page size. */
87 # define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
88 /* Internal flash lock region size. */
89 # define IFLASH_LOCK_REGION_SIZE IFLASH0_LOCK_REGION_SIZE
90 #elif (SAM3XA || SAM3U4)
91 /* Internal Flash Controller 0. */
92 # define EFC EFC0
93 /* The max GPNVM number. */
94 # define GPNVM_NUM_MAX 3
95 /* Internal Flash 0 base address. */
96 # define IFLASH_ADDR IFLASH0_ADDR
97 /* Internal flash page size. */
98 # define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
99 /* Internal flash lock region size. */
100 # define IFLASH_LOCK_REGION_SIZE IFLASH0_LOCK_REGION_SIZE
101 #elif (SAM3U)
102 /* There is no EFC1 for SAM3U except for SAM3U4 */
103 # undef EFC1
104 /* Internal Flash Controller 0. */
105 # define EFC EFC0
106 /* The max GPNVM number. */
107 # define GPNVM_NUM_MAX 2
108 /* Internal Flash 0 base address. */
109 # define IFLASH_ADDR IFLASH0_ADDR
110 /* Internal flash page size. */
111 # define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
112 /* Internal flash lock region size. */
113 # define IFLASH_LOCK_REGION_SIZE IFLASH0_LOCK_REGION_SIZE
114 #elif (SAM3S8 || SAM3SD8)
115 /* The max GPNVM number. */
116 # define GPNVM_NUM_MAX 3
117 /* Internal flash page size. */
118 # define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
119 /* Internal flash lock region size. */
120 # define IFLASH_LOCK_REGION_SIZE IFLASH0_LOCK_REGION_SIZE
121 #elif (SAM4C32 || SAM4CMP32 || SAM4CMS32)
122 /* The max GPNVM number SAM4C(M)32. */
123 # define GPNVM_NUM_MAX 3
124 #elif (SAMG)
125 /* The max GPNVM number SAMG. */
126 # define GPNVM_NUM_MAX 8
127 #elif (SAMV71 || SAMV70 || SAMS70 || SAME70)
128 /* The max GPNVM number SAMV/S/E. */
129 # define GPNVM_NUM_MAX 9
130 #else
131 /* The max GPNVM number. */
132 # define GPNVM_NUM_MAX 2
133 #endif
134 
135 #if (SAM4C || SAM4CP || SAM4CM)
136 #if (SAM4C32 || SAM4CMP32 || SAM4CMS32)
137 # define EFC EFC0
138 /* Internal Flash 0 base address. */
139 # define IFLASH0_ADDR IFLASH0_CNC_ADDR
140 # define IFLASH1_ADDR IFLASH1_CNC_ADDR
141 # define IFLASH_ADDR IFLASH0_ADDR
142 /* Internal flash page size. */
143 # define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
144 /* Internal flash lock region size. */
145 # define IFLASH_LOCK_REGION_SIZE IFLASH0_LOCK_REGION_SIZE
146 #else
147 #define IFLASH_ADDR IFLASH_CNC_ADDR
148 #endif
149 #endif
150 
151 /* Flash page buffer for alignment */
152 static uint32_t gs_ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
153 
164 static void translate_address(Efc **pp_efc, uint32_t ul_addr,
165  uint16_t *pus_page, uint16_t *pus_offset)
166 {
167  Efc *p_efc;
168  uint16_t us_page;
169  uint16_t us_offset;
170 
171 #if (SAM3XA || SAM3U4)
172  if (ul_addr >= IFLASH1_ADDR) {
173  p_efc = EFC1;
174  us_page = (ul_addr - IFLASH1_ADDR) / IFLASH1_PAGE_SIZE;
175  us_offset = (ul_addr - IFLASH1_ADDR) % IFLASH1_PAGE_SIZE;
176  } else {
177  p_efc = EFC0;
178  us_page = (ul_addr - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE;
179  us_offset = (ul_addr - IFLASH0_ADDR) % IFLASH0_PAGE_SIZE;
180  }
181 #elif (SAM4SD16 || SAM4SD32 || SAM4C32 || SAM4CMP32 || SAM4CMS32)
182  uint32_t uc_gpnvm2;
183  uc_gpnvm2 = flash_is_gpnvm_set(2);
184  if (ul_addr >= IFLASH1_ADDR) {
185  if(uc_gpnvm2 == FLASH_RC_YES) {
186  p_efc = EFC0;
187  } else {
188  p_efc = EFC1;
189  }
190  us_page = (ul_addr - IFLASH1_ADDR) / IFLASH1_PAGE_SIZE;
191  us_offset = (ul_addr - IFLASH1_ADDR) % IFLASH1_PAGE_SIZE;
192  } else {
193  if(uc_gpnvm2 == FLASH_RC_YES) {
194  p_efc = EFC1;
195  } else {
196  p_efc = EFC0;
197  }
198  us_page = (ul_addr - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE;
199  us_offset = (ul_addr - IFLASH0_ADDR) % IFLASH0_PAGE_SIZE;
200  }
201 #elif (SAM3S8 || SAM3SD8)
202  p_efc = EFC;
203  us_page = (ul_addr - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE;
204  us_offset = (ul_addr - IFLASH0_ADDR) % IFLASH0_PAGE_SIZE;
205 #else
206  Assert(ul_addr >= IFLASH_ADDR);
207  Assert(ul_addr <= (IFLASH_ADDR + IFLASH_SIZE));
208 
209  p_efc = EFC;
210  us_page = (ul_addr - IFLASH_ADDR) / IFLASH_PAGE_SIZE;
211  us_offset = (ul_addr - IFLASH_ADDR) % IFLASH_PAGE_SIZE;
212 #endif
213 
214  /* Store values */
215  if (pp_efc) {
216  *pp_efc = p_efc;
217  }
218 
219  if (pus_page) {
220  *pus_page = us_page;
221  }
222 
223  if (pus_offset) {
224  *pus_offset = us_offset;
225  }
226 }
227 
236 static void compute_address(Efc *p_efc, uint16_t us_page, uint16_t us_offset,
237  uint32_t *pul_addr)
238 {
239  uint32_t ul_addr;
240 
241 /* Dual bank flash */
242 #ifdef EFC1
243  /* Compute address */
244 #if (SAM4SD16 || SAM4SD32 || SAM4C32 || SAM4CMP32 || SAM4CMS32)
245  uint32_t uc_gpnvm2;
246  uc_gpnvm2 = flash_is_gpnvm_set(2);
247  if (p_efc == EFC0) {
248  if(uc_gpnvm2 == FLASH_RC_YES) {
249  ul_addr = IFLASH1_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset;
250  } else {
251  ul_addr = IFLASH0_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset;
252  }
253  } else {
254  if(uc_gpnvm2 == FLASH_RC_YES) {
255  ul_addr = IFLASH0_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset;
256  } else {
257  ul_addr = IFLASH1_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset;
258  }
259  }
260 #else
261  ul_addr = (p_efc == EFC0) ?
262  IFLASH0_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset :
263  IFLASH1_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset;
264 #endif
265 /* One bank flash */
266 #else
267  /* avoid Cppcheck Warning */
268  UNUSED(p_efc);
269  /* Compute address */
270  ul_addr = IFLASH_ADDR + us_page * IFLASH_PAGE_SIZE + us_offset;
271 #endif
272 
273  /* Store result */
274  if (pul_addr != NULL) {
275  *pul_addr = ul_addr;
276  }
277 }
278 
287 static void compute_lock_range(uint32_t ul_start, uint32_t ul_end,
288  uint32_t *pul_actual_start, uint32_t *pul_actual_end)
289 {
290  uint32_t ul_actual_start, ul_actual_end;
291 
292  ul_actual_start = ul_start - (ul_start % IFLASH_LOCK_REGION_SIZE);
293  ul_actual_end = ul_end - (ul_end % IFLASH_LOCK_REGION_SIZE) +
295 
296  if (pul_actual_start) {
297  *pul_actual_start = ul_actual_start;
298  }
299 
300  if (pul_actual_end) {
301  *pul_actual_end = ul_actual_end;
302  }
303 }
304 
313 uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws)
314 {
315  efc_init(EFC, ul_mode, ul_fws);
316 
317 #ifdef EFC1
318  efc_init(EFC1, ul_mode, ul_fws);
319 #endif
320 
321  return FLASH_RC_OK;
322 }
323 
332 uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws)
333 {
334  Efc *p_efc;
335 
336  translate_address(&p_efc, ul_address, NULL, NULL);
337  efc_set_wait_state(p_efc, ul_fws);
338 
339  return FLASH_RC_OK;
340 }
341 
350 uint32_t flash_set_wait_state_adaptively(uint32_t ul_address)
351 {
352  Efc *p_efc;
353  uint32_t clock = sysclk_get_cpu_hz();
354 
355  translate_address(&p_efc, ul_address, NULL, NULL);
356 
357  /* Set FWS for embedded Flash access according to operating frequency */
358  if (clock < CHIP_FREQ_FWS_0) {
359  efc_set_wait_state(p_efc, 0);
360  } else if (clock < CHIP_FREQ_FWS_1) {
361  efc_set_wait_state(p_efc, 1);
362  } else if (clock < CHIP_FREQ_FWS_2) {
363  efc_set_wait_state(p_efc, 2);
364 #if (SAM3XA || SAM3U)
365  } else if (clock < CHIP_FREQ_FWS_3) {
366  efc_set_wait_state(p_efc, 3);
367  } else {
368  efc_set_wait_state(p_efc, 4);
369  }
370 #elif (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || \
371  SAMV71 || SAMV70 || SAMS70 || SAME70)
372  } else if (clock < CHIP_FREQ_FWS_3) {
373  efc_set_wait_state(p_efc, 3);
374  } else if (clock < CHIP_FREQ_FWS_4) {
375  efc_set_wait_state(p_efc, 4);
376  } else {
377  efc_set_wait_state(p_efc, 5);
378  }
379 #else
380  } else {
381  efc_set_wait_state(p_efc, 3);
382  }
383 #endif
384 
385  return FLASH_RC_OK;
386 }
387 
395 uint32_t flash_get_wait_state(uint32_t ul_address)
396 {
397  Efc *p_efc;
398 
399  translate_address(&p_efc, ul_address, NULL, NULL);
400  return efc_get_wait_state(p_efc);
401 }
402 
412 uint32_t flash_get_descriptor(uint32_t ul_address,
413  uint32_t *pul_flash_descriptor, uint32_t ul_size)
414 {
415  Efc *p_efc;
416  uint32_t ul_tmp;
417  uint32_t ul_cnt;
418 
419  translate_address(&p_efc, ul_address, NULL, NULL);
420 
421  /* Command fails */
422  if (FLASH_RC_OK != efc_perform_command(p_efc, EFC_FCMD_GETD, 0)) {
423  return 0;
424  } else {
425  /* Read until no result */
426  for (ul_cnt = 0;; ul_cnt++) {
427  ul_tmp = efc_get_result(p_efc);
428  if ((ul_size > ul_cnt) && (ul_tmp != 0)) {
429  *pul_flash_descriptor++ = ul_tmp;
430  } else {
431  break;
432  }
433  }
434  }
435 
436  return ul_cnt;
437 }
438 
449 uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor)
450 {
451  return (pul_flash_descriptor[1] / pul_flash_descriptor[2]);
452 }
453 
464 uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor)
465 {
466  return (pul_flash_descriptor[4] / pul_flash_descriptor[2]);
467 }
468 
479 uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor)
480 {
481  return (pul_flash_descriptor[3]);
482 }
483 
495 uint32_t flash_erase_all(uint32_t ul_address)
496 {
497  Efc *p_efc;
498 
499  translate_address(&p_efc, ul_address, NULL, NULL);
500 
501  if (EFC_RC_OK != efc_perform_command(p_efc, EFC_FCMD_EA, 0)) {
502  return FLASH_RC_ERROR;
503  }
504 
505  return FLASH_RC_OK;
506 }
507 
508 #if (SAM3S8 || SAM3SD8)
509 
519 uint32_t flash_erase_plane(uint32_t ul_address)
520 {
521  Efc *p_efc;
522  uint16_t us_page;
523 
524  translate_address(&p_efc, ul_address, &us_page, NULL);
525 
526  if (EFC_RC_OK != efc_perform_command(p_efc, EFC_FCMD_EPL, us_page)) {
527  return FLASH_RC_ERROR;
528  }
529 
530  return FLASH_RC_OK;
531 }
532 #endif
533 
534 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
535  SAMV71 || SAMV70 || SAMS70 || SAME70)
536 
543 uint32_t flash_erase_page(uint32_t ul_address, uint8_t uc_page_num)
544 {
545  Efc *p_efc;
546  uint16_t us_page;
547 
548  if (uc_page_num >= IFLASH_ERASE_PAGES_INVALID) {
549  return FLASH_RC_INVALID;
550  }
551 
552  if (ul_address & (IFLASH_PAGE_SIZE - 1)) {
553  return FLASH_RC_INVALID;
554  }
555 
556  translate_address(&p_efc, ul_address, &us_page, NULL);
557 
558  if (EFC_RC_OK != efc_perform_command(p_efc, EFC_FCMD_EPA,
559  (us_page | uc_page_num))) {
560  return FLASH_RC_ERROR;
561  }
562 
563  return FLASH_RC_OK;
564 }
565 
576 uint32_t flash_erase_sector(uint32_t ul_address)
577 {
578  Efc *p_efc;
579  uint16_t us_page;
580 
581  translate_address(&p_efc, ul_address, &us_page, NULL);
582 
583  if (EFC_RC_OK != efc_perform_command(p_efc, EFC_FCMD_ES, us_page)) {
584  return FLASH_RC_ERROR;
585  }
586 
587  return FLASH_RC_OK;
588 }
589 #endif
590 
607 uint32_t flash_write(uint32_t ul_address, const void *p_buffer,
608  uint32_t ul_size, uint32_t ul_erase_flag)
609 {
610  Efc *p_efc;
611  uint32_t ul_fws_temp;
612  uint16_t us_page;
613  uint16_t us_offset;
614  uint32_t writeSize;
615  uint32_t ul_page_addr;
616  uint16_t us_padding;
617  uint32_t ul_error;
618  uint32_t ul_idx;
619  uint32_t *p_aligned_dest;
620  uint8_t *puc_page_buffer = (uint8_t *) gs_ul_page_buffer;
621 
622  translate_address(&p_efc, ul_address, &us_page, &us_offset);
623 
624 #if SAM3S || SAM3N || SAM3XA || SAM3U
625  /* According to the errata, set the wait state value to 6. */
626  ul_fws_temp = efc_get_wait_state(p_efc);
627  efc_set_wait_state(p_efc, 6);
628 #else
629  UNUSED(ul_fws_temp);
630 #endif
631 
632  /* Write all pages */
633  while (ul_size > 0) {
634  /* Copy data in temporary buffer to avoid alignment problems. */
635  writeSize = Min((uint32_t) IFLASH_PAGE_SIZE - us_offset,
636  ul_size);
637  compute_address(p_efc, us_page, 0, &ul_page_addr);
638  us_padding = IFLASH_PAGE_SIZE - us_offset - writeSize;
639 
640  /* Pre-buffer data */
641  memcpy(puc_page_buffer, (void *)ul_page_addr, us_offset);
642 
643  /* Buffer data */
644  memcpy(puc_page_buffer + us_offset, p_buffer, writeSize);
645 
646  /* Post-buffer data */
647  memcpy(puc_page_buffer + us_offset + writeSize,
648  (void *)(ul_page_addr + us_offset + writeSize),
649  us_padding);
650 
651  /* Write page.
652  * Writing 8-bit and 16-bit data is not allowed and may lead to
653  * unpredictable data corruption.
654  */
655  uint32_t tmp;
656  p_aligned_dest = (uint32_t *) ul_page_addr;
657  for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / sizeof(uint32_t)); ++ul_idx)
658  {
659  tmp = gs_ul_page_buffer[ul_idx];
660  *p_aligned_dest = tmp;
661  p_aligned_dest++;
662  }
663 
664  if (ul_erase_flag) {
665  ul_error = efc_perform_command(p_efc, EFC_FCMD_EWP,
666  us_page);
667  } else {
668  ul_error = efc_perform_command(p_efc, EFC_FCMD_WP,
669  us_page);
670  }
671 
672  if (ul_error) {
673  return ul_error;
674  }
675 
676  /* Progression */
677  p_buffer = (void *)((uint32_t) p_buffer + writeSize);
678  ul_size -= writeSize;
679  us_page++;
680  us_offset = 0;
681  }
682 
683 #if SAM3S || SAM3N || SAM3XA || SAM3U
684  /* According to the errata, restore the wait state value. */
685  efc_set_wait_state(p_efc, ul_fws_temp);
686 #endif
687 
688  return FLASH_RC_OK;
689 }
690 
691 
703 uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end,
704  uint32_t *pul_actual_start, uint32_t *pul_actual_end)
705 {
706  Efc *p_efc;
707  uint32_t ul_actual_start, ul_actual_end;
708  uint16_t us_start_page, us_end_page;
709  uint32_t ul_error;
710  uint16_t us_num_pages_in_region =
712 
713  /* Compute actual lock range and store it */
714  compute_lock_range(ul_start, ul_end, &ul_actual_start, &ul_actual_end);
715 
716  if (pul_actual_start != NULL) {
717  *pul_actual_start = ul_actual_start;
718  }
719 
720  if (pul_actual_end != NULL) {
721  *pul_actual_end = ul_actual_end;
722  }
723 
724  /* Compute page numbers */
725  translate_address(&p_efc, ul_actual_start, &us_start_page, 0);
726  translate_address(0, ul_actual_end, &us_end_page, 0);
727 
728  /* Lock all pages */
729  while (us_start_page < us_end_page) {
730  ul_error = efc_perform_command(p_efc, EFC_FCMD_SLB, us_start_page);
731 
732  if (ul_error) {
733  return ul_error;
734  }
735  us_start_page += us_num_pages_in_region;
736  }
737 
738  return FLASH_RC_OK;
739 }
740 
752 uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end,
753  uint32_t *pul_actual_start, uint32_t *pul_actual_end)
754 {
755  Efc *p_efc;
756  uint32_t ul_actual_start, ul_actual_end;
757  uint16_t us_start_page, us_end_page;
758  uint32_t ul_error;
759  uint16_t us_num_pages_in_region =
761 
762  /* Compute actual unlock range and store it */
763  compute_lock_range(ul_start, ul_end, &ul_actual_start, &ul_actual_end);
764  if (pul_actual_start != NULL) {
765  *pul_actual_start = ul_actual_start;
766  }
767  if (pul_actual_end != NULL) {
768  *pul_actual_end = ul_actual_end;
769  }
770 
771  /* Compute page numbers */
772  translate_address(&p_efc, ul_actual_start, &us_start_page, 0);
773  translate_address(0, ul_actual_end, &us_end_page, 0);
774 
775  /* Unlock all pages */
776  while (us_start_page < us_end_page) {
777  ul_error = efc_perform_command(p_efc, EFC_FCMD_CLB,
778  us_start_page);
779  if (ul_error) {
780  return ul_error;
781  }
782  us_start_page += us_num_pages_in_region;
783  }
784 
785  return FLASH_RC_OK;
786 }
787 
796 uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end)
797 {
798  Efc *p_efc;
799  uint16_t us_start_page, us_end_page;
800  uint8_t uc_start_region, uc_end_region;
801  uint16_t us_num_pages_in_region;
802  uint32_t ul_status;
803  uint32_t ul_error;
804  uint32_t ul_num_locked_regions = 0;
805  uint32_t ul_count = 0;
806  uint32_t ul_bit = 0;
807 
808  Assert(ul_end >= ul_start);
809 
810 #ifdef EFC1
811  Assert(((ul_start >= IFLASH0_ADDR)
812  && (ul_end <= IFLASH0_ADDR + IFLASH0_SIZE))
813  || ((ul_start >= IFLASH1_ADDR)
814  && (ul_end <= IFLASH1_ADDR + IFLASH1_SIZE)));
815 #else
816  Assert((ul_start >= IFLASH_ADDR)
817  && (ul_end <= IFLASH_ADDR + IFLASH_SIZE));
818 #endif
819 
820  /* Compute page numbers */
821  translate_address(&p_efc, ul_start, &us_start_page, 0);
822  translate_address(0, ul_end, &us_end_page, 0);
823 
824  /* Compute region numbers */
825  us_num_pages_in_region = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
826  uc_start_region = us_start_page / us_num_pages_in_region;
827  uc_end_region = us_end_page / us_num_pages_in_region;
828 
829  /* Retrieve lock status */
830  ul_error = efc_perform_command(p_efc, EFC_FCMD_GLB, 0);
831  if (ul_error) {
832  return ul_error;
833  }
834  UNUSED(ul_error);
835 
836  /* Skip unrequested regions (if necessary) */
837  ul_status = efc_get_result(p_efc);
838  while (!(ul_count <= uc_start_region &&
839  uc_start_region < (ul_count + 32))) {
840  ul_status = efc_get_result(p_efc);
841  ul_count += 32;
842  }
843 
844  /* Check status of each involved region */
845  ul_bit = uc_start_region - ul_count;
846 
847  /* Number of region to check (must be > 0) */
848  ul_count = uc_end_region - uc_start_region + 1;
849 
850  while (ul_count > 0) {
851  if (ul_status & (1 << (ul_bit))) {
852  ul_num_locked_regions++;
853  }
854 
855  ul_count -= 1;
856  ul_bit += 1;
857  if (ul_bit == 32) {
858  ul_status = efc_get_result(p_efc);
859  ul_bit = 0;
860  }
861  }
862 
863  return ul_num_locked_regions;
864 }
865 
873 uint32_t flash_set_gpnvm(uint32_t ul_gpnvm)
874 {
875  if (ul_gpnvm >= GPNVM_NUM_MAX) {
876  return FLASH_RC_INVALID;
877  }
878 
879  if (FLASH_RC_YES == flash_is_gpnvm_set(ul_gpnvm)) {
880  return FLASH_RC_OK;
881  }
882 
883  if (EFC_RC_OK == efc_perform_command(EFC, EFC_FCMD_SGPB, ul_gpnvm)) {
884  return FLASH_RC_OK;
885  }
886 
887  return FLASH_RC_ERROR;
888 }
889 
897 uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm)
898 {
899  if (ul_gpnvm >= GPNVM_NUM_MAX) {
900  return FLASH_RC_INVALID;
901  }
902 
903  if (FLASH_RC_NO == flash_is_gpnvm_set(ul_gpnvm)) {
904  return FLASH_RC_OK;
905  }
906 
907  if (EFC_RC_OK == efc_perform_command(EFC, EFC_FCMD_CGPB, ul_gpnvm)) {
908  return FLASH_RC_OK;
909  }
910 
911  return FLASH_RC_ERROR;
912 }
913 
923 uint32_t flash_is_gpnvm_set(uint32_t ul_gpnvm)
924 {
925  uint32_t ul_gpnvm_bits;
926 
927  if (ul_gpnvm >= GPNVM_NUM_MAX) {
928  return FLASH_RC_INVALID;
929  }
930 
932  return FLASH_RC_ERROR;
933  }
934 
935  ul_gpnvm_bits = efc_get_result(EFC);
936  if (ul_gpnvm_bits & (1 << ul_gpnvm)) {
937  return FLASH_RC_YES;
938  }
939 
940  return FLASH_RC_NO;
941 }
942 
949 {
950  return flash_set_gpnvm(0);
951 }
952 
961 {
962  return flash_is_gpnvm_set(0);
963 }
964 
973 uint32_t flash_read_unique_id(uint32_t *pul_data, uint32_t ul_size)
974 {
975  uint32_t uid_buf[4];
976  uint32_t ul_idx;
977 
979  EFC_FCMD_SPUI, uid_buf, 4)) {
980  return FLASH_RC_ERROR;
981  }
982 
983  if (ul_size > 4) {
984  /* Only 4 dword to store unique ID */
985  ul_size = 4;
986  }
987 
988  for (ul_idx = 0; ul_idx < ul_size; ul_idx++) {
989  pul_data[ul_idx] = uid_buf[ul_idx];
990  }
991 
992  return FLASH_RC_OK;
993 }
994 
995 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
996  SAMV71 || SAMV70 || SAMS70 || SAME70)
997 
1005 uint32_t flash_read_user_signature(uint32_t *p_data, uint32_t ul_size)
1006 {
1007  if (ul_size > (FLASH_USER_SIG_SIZE / sizeof(uint32_t))) {
1008  /* Only 512 byte to store user signature */
1009  ul_size = FLASH_USER_SIG_SIZE / sizeof(uint32_t);
1010  }
1011 
1012  /* Send the read user signature commands */
1013  if (FLASH_RC_OK != efc_perform_read_sequence(EFC, EFC_FCMD_STUS,
1014  EFC_FCMD_SPUS, p_data, ul_size)) {
1015  return FLASH_RC_ERROR;
1016  }
1017 
1018  return FLASH_RC_OK;
1019 }
1020 
1029 uint32_t flash_write_user_signature(const void *p_buffer, uint32_t ul_size)
1030 {
1031  uint32_t ul_idx;
1032  uint32_t *p_dest;
1033 
1034  /* The user signature should be no longer than 512 bytes */
1035  if (ul_size > (IFLASH_PAGE_SIZE / sizeof(uint32_t))) {
1036  return FLASH_RC_INVALID;
1037  }
1038 
1039  /* Copy Buffer data */
1040  memcpy((uint8_t *) gs_ul_page_buffer, p_buffer,
1041  ul_size * sizeof(uint32_t));
1042 
1043  /* Write page buffer.
1044  * Writing 8-bit and 16-bit data is not allowed and may lead to
1045  * unpredictable data corruption.
1046  */
1047  p_dest = (uint32_t *)IFLASH_ADDR;
1048  for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / sizeof(uint32_t));
1049  ul_idx++) {
1050  *p_dest++ = gs_ul_page_buffer[ul_idx];
1051  }
1052 
1053  /* Send the write signature command */
1054  if (FLASH_RC_OK != efc_perform_command(EFC, EFC_FCMD_WUS, 0)) {
1055  return FLASH_RC_ERROR;
1056  }
1057 
1058  return FLASH_RC_OK;
1059 }
1060 
1066 uint32_t flash_erase_user_signature(void)
1067 {
1068  /* Perform the erase user signature command */
1069  return efc_perform_command(EFC, EFC_FCMD_EUS, 0);
1070 }
1071 #endif
1072 
1074 
1076 
1077 #ifdef __cplusplus
1078 }
1079 #endif
1080 
1081 
Operation OK.
Definition: flash_efc.h:64
#define UNUSED(v)
Marking v as a unused parameter or value.
Definition: compiler.h:86
uint32_t flash_enable_security_bit(void)
Set security bit.
Definition: flash_efc.c:948
uint32_t efc_init(Efc *p_efc, uint32_t ul_access_mode, uint32_t ul_fws)
Initialize the EFC controller.
Definition: efc.c:119
uint32_t efc_get_wait_state(Efc *p_efc)
Get flash wait state.
Definition: efc.c:248
#define EFC_FCMD_STUI
Start unique ID.
static uint32_t sysclk_get_cpu_hz(void)
Return the current rate in Hz of the CPU clock.
uint32_t flash_init(uint32_t ul_mode, uint32_t ul_fws)
Initialize the flash service.
Definition: flash_efc.c:313
Embedded Flash service for SAM.
#define EFC_FCMD_CLB
Clear Lock Bit.
#define Min(a, b)
Takes the minimal value of a and b.
Definition: compiler.h:786
uint32_t flash_get_page_count(const uint32_t *pul_flash_descriptor)
Get flash total page count for the specified bank.
Definition: flash_efc.c:449
#define EFC_FCMD_SGPB
Set GPNVM Bit.
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command, uint32_t ul_argument)
Perform the given command and wait until its completion (or an error).
Definition: efc.c:266
#define EFC_FCMD_GGPB
Get GPNVM Bit.
Operation OK.
#define NULL
Definition: nm_bsp.h:52
void efc_set_wait_state(Efc *p_efc, uint32_t ul_fws)
Set flash wait state.
Definition: efc.c:234
#define IFLASH_LOCK_REGION_SIZE
Definition: same70j19.h:558
#define CHIP_FREQ_FWS_0
Maximum operating frequency when FWS is 0.
Definition: same70j19.h:597
Efc hardware registers.
#define EFC_FCMD_EWP
Erase page and write page.
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
Lock all the regions in the given address range. The actual lock range is reported through two output...
Definition: flash_efc.c:703
__no_inline RAMFUNC uint32_t efc_perform_read_sequence(Efc *p_efc, uint32_t ul_cmd_st, uint32_t ul_cmd_sp, uint32_t *p_ul_buf, uint32_t ul_size)
Perform read sequence. Supported sequences are read Unique ID and read User Signature.
Definition: efc.c:326
#define EFC_FCMD_WP
Write page.
uint32_t flash_clear_gpnvm(uint32_t ul_gpnvm)
Clear the given GPNVM bit.
Definition: flash_efc.c:897
uint32_t flash_is_locked(uint32_t ul_start, uint32_t ul_end)
Get the number of locked regions inside the given address range.
Definition: flash_efc.c:796
uint32_t flash_erase_all(uint32_t ul_address)
Erase the entire flash.
Definition: flash_efc.c:495
#define EFC_FCMD_SLB
Set Lock Bit.
static uint32_t gs_ul_page_buffer[IFLASH_PAGE_SIZE/sizeof(uint32_t)]
Definition: flash_efc.c:152
static void compute_lock_range(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
Compute the lock range associated with the given address range.
Definition: flash_efc.c:287
uint32_t efc_get_result(Efc *p_efc)
Get the result of the last executed command.
Definition: efc.c:307
#define EFC_FCMD_SPUI
Stop unique ID.
#define IFLASH_PAGE_SIZE
Definition: same70j19.h:557
static void translate_address(Efc **pp_efc, uint32_t ul_addr, uint16_t *pus_page, uint16_t *pus_offset)
Translate the given flash address to page and offset values.
Definition: flash_efc.c:164
uint32_t flash_set_wait_state_adaptively(uint32_t ul_address)
Set flash wait state.
Definition: flash_efc.c:350
General error.
Definition: flash_efc.h:67
Invalid argument input.
Definition: flash_efc.h:68
static void compute_address(Efc *p_efc, uint16_t us_page, uint16_t us_offset, uint32_t *pul_addr)
Compute the address of a flash by the given page and offset.
Definition: flash_efc.c:236
#define EFC_FCMD_GETD
Get Flash Descriptor.
uint32_t flash_get_page_count_per_region(const uint32_t *pul_flash_descriptor)
Get flash page count per region (plane) for the specified bank.
Definition: flash_efc.c:464
#define CHIP_FREQ_FWS_3
Maximum operating frequency when FWS is 3.
Definition: same70j19.h:600
#define EFC
(EFC ) Base Address
Definition: same70j19.h:528
uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size, uint32_t ul_erase_flag)
Write a data buffer on flash.
Definition: flash_efc.c:607
uint32_t flash_is_gpnvm_set(uint32_t ul_gpnvm)
Check if the given GPNVM bit is set or not.
Definition: flash_efc.c:923
#define IFLASH_ADDR
Definition: same70j19.h:566
uint32_t flash_get_descriptor(uint32_t ul_address, uint32_t *pul_flash_descriptor, uint32_t ul_size)
Get flash descriptor.
Definition: flash_efc.c:412
#define CHIP_FREQ_FWS_2
Maximum operating frequency when FWS is 2.
Definition: same70j19.h:599
#define CHIP_FREQ_FWS_4
Maximum operating frequency when FWS is 4.
Definition: same70j19.h:601
uint32_t flash_get_wait_state(uint32_t ul_address)
Get flash wait state.
Definition: flash_efc.c:395
uint32_t flash_is_security_bit_enabled(void)
Check if the security bit is set or not.
Definition: flash_efc.c:960
#define IFLASH_SIZE
Definition: same70j19.h:556
uint32_t flash_set_gpnvm(uint32_t ul_gpnvm)
Set the given GPNVM bit.
Definition: flash_efc.c:873
#define EFC_FCMD_EA
Erase all.
#define GPNVM_NUM_MAX
Definition: flash_efc.c:132
#define Assert(expr)
This macro is used to test fatal errors.
Definition: compiler.h:196
uint32_t flash_set_wait_state(uint32_t ul_address, uint32_t ul_fws)
Set flash wait state.
Definition: flash_efc.c:332
#define CHIP_FREQ_FWS_1
Maximum operating frequency when FWS is 1.
Definition: same70j19.h:598
uint32_t flash_get_region_count(const uint32_t *pul_flash_descriptor)
Get flash region (plane) count for the specified bank.
Definition: flash_efc.c:479
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
Unlock all the regions in the given address range. The actual unlock range is reported through two ou...
Definition: flash_efc.c:752
#define EFC_FCMD_CGPB
Clear GPNVM Bit.
#define EFC_FCMD_GLB
Get Lock Bit.
uint32_t flash_read_unique_id(uint32_t *pul_data, uint32_t ul_size)
Read the flash unique ID.
Definition: flash_efc.c:973


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:57