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 "efc.h"
48 
50 
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54 
55 
66 /* Address definition for read operation */
67 #if (SAM3XA || SAM3U4 || SAM4SD16 || SAM4SD32)
68 # define READ_BUFF_ADDR0 IFLASH0_ADDR
69 # define READ_BUFF_ADDR1 IFLASH1_ADDR
70 #elif (SAM3S || SAM3N || SAM4E || SAM4N || SAMG || SAMV71 || SAMV70 || SAMS70 || SAME70)
71 # define READ_BUFF_ADDR IFLASH_ADDR
72 #elif (SAM4C || SAM4CP || SAM4CM)
73 #if (SAM4C32 || SAM4CMS32 || SAM4CMP32)
74 # define READ_BUFF_ADDR0 IFLASH0_CNC_ADDR
75 # define READ_BUFF_ADDR1 IFLASH1_CNC_ADDR
76 #else
77 # define READ_BUFF_ADDR IFLASH_CNC_ADDR
78 #endif
79 #elif (SAM3U || SAM4S)
80 # define READ_BUFF_ADDR IFLASH0_ADDR
81 #else
82 # warning Only reading unique ID for sam3/4 is implemented.
83 #endif
84 
85 /* Flash Writing Protection Key */
86 #define FWP_KEY 0x5Au
87 
88 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM)
89 #define EEFC_FCR_FCMD(value) \
90  ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
91 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR)
92 #elif (SAMV71 || SAMV70 || SAMS70 || SAME70)
93 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR \
94  | EEFC_FSR_UECCELSB | EEFC_FSR_MECCELSB | EEFC_FSR_UECCEMSB | EEFC_FSR_MECCEMSB)
95 #else
96 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
97 #endif
98 
99 #ifndef EEFC_FCR_FKEY_PASSWD
100 #define EEFC_FCR_FKEY_PASSWD EEFC_FCR_FKEY(FWP_KEY)
101 #endif
102 
103 
104 /*
105  * Local function declaration.
106  * Because they are RAM functions, they need 'extern' declaration.
107  */
108 extern void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr);
109 extern uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr);
110 
119 uint32_t efc_init(Efc *p_efc, uint32_t ul_access_mode, uint32_t ul_fws)
120 {
121 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
122  SAMV71 || SAMV70 || SAMS70 || SAME70)
123  efc_write_fmr(p_efc, ul_access_mode | EEFC_FMR_FWS(ul_fws) | EEFC_FMR_CLOE);
124 #else
125  efc_write_fmr(p_efc, ul_access_mode | EEFC_FMR_FWS(ul_fws));
126 #endif
127  return EFC_RC_OK;
128 }
129 
130 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
131  SAMV71 || SAMV70 || SAMS70 || SAME70)
132 
137 void efc_enable_cloe(Efc *p_efc)
138 {
139  uint32_t ul_fmr = p_efc->EEFC_FMR;
140  efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_CLOE);
141 }
142 
148 void efc_disable_cloe(Efc *p_efc)
149 {
150  uint32_t ul_fmr = p_efc->EEFC_FMR;
151  efc_write_fmr(p_efc, ul_fmr & (~EEFC_FMR_CLOE));
152 }
153 #endif
154 
155 
156 
163 {
164  uint32_t ul_fmr = p_efc->EEFC_FMR;
165 
166  efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_FRDY);
167 }
168 
175 {
176  uint32_t ul_fmr = p_efc->EEFC_FMR;
177 
178  efc_write_fmr(p_efc, ul_fmr & (~EEFC_FMR_FRDY));
179 }
180 
181 #if (SAMV71 || SAMV70 || SAMS70 || SAME70)
182 
187 void efc_enable_write_protection(Efc *p_efc)
188 {
190 }
191 
197 void efc_disable_write_protection(Efc *p_efc)
198 {
200 }
201 #else
202 
208 void efc_set_flash_access_mode(Efc *p_efc, uint32_t ul_mode)
209 {
210  uint32_t ul_fmr = p_efc->EEFC_FMR & (~EEFC_FMR_FAM);
211 
212  efc_write_fmr(p_efc, ul_fmr | ul_mode);
213 }
214 
223 {
224  return (p_efc->EEFC_FMR & EEFC_FMR_FAM);
225 }
226 #endif
227 
234 void efc_set_wait_state(Efc *p_efc, uint32_t ul_fws)
235 {
236  uint32_t ul_fmr = p_efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk);
237 
238  efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_FWS(ul_fws));
239 }
240 
248 uint32_t efc_get_wait_state(Efc *p_efc)
249 {
250  return ((p_efc->EEFC_FMR & EEFC_FMR_FWS_Msk) >> EEFC_FMR_FWS_Pos);
251 }
252 
266 uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
267  uint32_t ul_argument)
268 {
269  uint32_t result;
270  irqflags_t flags;
271 
272  /* Unique ID commands are not supported. */
273  if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
274  return EFC_RC_NOT_SUPPORT;
275  }
276 
277  flags = cpu_irq_save();
278  /* Use RAM Function. */
279  result = efc_perform_fcr(p_efc,
280  EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
281  EEFC_FCR_FCMD(ul_command));
282  cpu_irq_restore(flags);
283  return result;
284 }
285 
295 uint32_t efc_get_status(Efc *p_efc)
296 {
297  return p_efc->EEFC_FSR;
298 }
299 
307 uint32_t efc_get_result(Efc *p_efc)
308 {
309  return p_efc->EEFC_FRR;
310 }
311 
324 __no_inline
325 RAMFUNC
327  uint32_t ul_cmd_st, uint32_t ul_cmd_sp,
328  uint32_t *p_ul_buf, uint32_t ul_size)
329 {
330  volatile uint32_t ul_status;
331  uint32_t ul_cnt;
332 
333 #if (SAM3U4 || SAM3XA || SAM4SD16 || SAM4SD32 || SAM4C32 || SAM4CMS32|| SAM4CMP32)
334  uint32_t *p_ul_data =
335  (uint32_t *) ((p_efc == EFC0) ?
336  READ_BUFF_ADDR0 : READ_BUFF_ADDR1);
337 #elif (SAM3S || SAM4S || SAM3N || SAM3U || SAM4E || SAM4N || SAM4C || SAMG || \
338  SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAMS70 || SAME70)
339  uint32_t *p_ul_data = (uint32_t *) READ_BUFF_ADDR;
340 #else
341  return EFC_RC_NOT_SUPPORT;
342 #endif
343 
344  if (p_ul_buf == NULL) {
345  return EFC_RC_INVALID;
346  }
347 
348  p_efc->EEFC_FMR |= (0x1u << 16);
349 
350  /* Send the Start Read command */
351 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
352  SAMV71 || SAMV70 || SAMS70 || SAME70)
354  | EEFC_FCR_FCMD(ul_cmd_st);
355 #else
357  | EEFC_FCR_FCMD(ul_cmd_st);
358 #endif
359  /* Wait for the FRDY bit in the Flash Programming Status Register
360  * (EEFC_FSR) falls.
361  */
362  do {
363  ul_status = p_efc->EEFC_FSR;
364  } while ((ul_status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
365 
366  /* The data is located in the first address of the Flash
367  * memory mapping.
368  */
369  for (ul_cnt = 0; ul_cnt < ul_size; ul_cnt++) {
370  p_ul_buf[ul_cnt] = p_ul_data[ul_cnt];
371  }
372 
373  /* To stop the read mode */
374  p_efc->EEFC_FCR =
375 #if (SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
376  SAMV71 || SAMV70 || SAMS70 || SAME70)
378  EEFC_FCR_FCMD(ul_cmd_sp);
379 #else
381  EEFC_FCR_FCMD(ul_cmd_sp);
382 #endif
383  /* Wait for the FRDY bit in the Flash Programming Status Register (EEFC_FSR)
384  * rises.
385  */
386  do {
387  ul_status = p_efc->EEFC_FSR;
388  } while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
389 
390  p_efc->EEFC_FMR &= ~(0x1u << 16);
391 
392  return EFC_RC_OK;
393 }
394 
401 __no_inline
402 RAMFUNC
403 void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr)
404 {
405  p_efc->EEFC_FMR = ul_fmr;
406 }
407 
416 __no_inline
417 RAMFUNC
418 uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
419 {
420  volatile uint32_t ul_status;
421 
422  p_efc->EEFC_FCR = ul_fcr;
423  do {
424  ul_status = p_efc->EEFC_FSR;
425  } while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
426 
427  return (ul_status & EEFC_ERROR_FLAGS);
428 }
429 
431 
433 
434 #ifdef __cplusplus
435 }
436 #endif
437 
438 
Invalid argument input.
#define EEFC_ERROR_FLAGS
Definition: efc.c:96
#define EEFC_WPMR_WPEN
(EEFC_WPMR) Write Protection Enable
#define RAMFUNC
Definition: ISConstants.h:251
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 FWP_KEY
Definition: efc.c:86
#define EFC_FCMD_STUI
Start unique ID.
__O uint32_t EEFC_FCR
(Efc Offset: 0x04) EEFC Flash Command Register
void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr)
Set mode register.
Definition: efc.c:403
static irqflags_t cpu_irq_save(void)
Get and clear the global interrupt flags.
Embedded Flash Controller (EFC) driver for SAM.
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 EEFC_FCR_FCMD(value)
uint32_t efc_get_status(Efc *p_efc)
Get the current status of the EEFC.
Definition: efc.c:295
void efc_set_flash_access_mode(Efc *p_efc, uint32_t ul_mode)
Set flash access mode.
Definition: efc.c:208
Operation OK.
#define EEFC_FCR_FARG(value)
#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
void efc_disable_frdy_interrupt(Efc *p_efc)
Disable the flash ready interrupt.
Definition: efc.c:174
Efc hardware registers.
__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
static void cpu_irq_restore(irqflags_t flags)
Restore global interrupt flags.
uint32_t efc_get_flash_access_mode(Efc *p_efc)
Get flash access mode.
Definition: efc.c:222
#define EEFC_FCR_FKEY_PASSWD
Definition: efc.c:100
uint32_t efc_get_result(Efc *p_efc)
Get the result of the last executed command.
Definition: efc.c:307
#define EEFC_FMR_FWS(value)
#define EFC_FCMD_SPUI
Stop unique ID.
#define EEFC_FMR_FRDY
(EEFC_FMR) Flash Ready Interrupt Enable
Operation is not supported.
uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
Perform command.
Definition: efc.c:418
__IO uint32_t EEFC_WPMR
(Efc Offset: 0xE4) Write Protection Mode Register
__I uint32_t EEFC_FRR
(Efc Offset: 0x0C) EEFC Flash Result Register
uint32_t irqflags_t
Type used for holding state of interrupt flag.
#define EEFC_FCR_FKEY(value)
#define EEFC_FMR_FWS_Msk
(EEFC_FMR) Flash Wait State
void efc_enable_frdy_interrupt(Efc *p_efc)
Enable the flash ready interrupt.
Definition: efc.c:162
#define EEFC_FSR_FRDY
(EEFC_FSR) Flash Ready Status (cleared when Flash is busy)
__I uint32_t EEFC_FSR
(Efc Offset: 0x08) EEFC Flash Status Register
#define EEFC_WPMR_WPKEY_PASSWD
(EEFC_WPMR) Writing any other value in this field aborts the write operation.Always reads as 0...
__IO uint32_t EEFC_FMR
(Efc Offset: 0x00) EEFC Flash Mode Register
#define EEFC_FMR_CLOE
(EEFC_FMR) Code Loop Optimization Enable


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