Go to the documentation of this file.00001
00044 #include "efc.h"
00045
00047
00048 #ifdef __cplusplus
00049 extern "C" {
00050 #endif
00051
00052
00053
00063
00064 # define READ_BUFF_ADDR0 IFLASH0_ADDR
00065 # define READ_BUFF_ADDR1 IFLASH1_ADDR
00066
00067
00068 #define FWP_KEY 0x5Au
00069
00070 #if (SAM4S || SAM4E)
00071 #define EEFC_FCR_FCMD(value) \
00072 ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
00073 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR)
00074 #else
00075 #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
00076 #endif
00077
00078
00079
00080
00081
00082
00083
00084 extern void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr);
00085 extern uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr);
00086
00095 uint32_t efc_init(Efc *p_efc, uint32_t ul_access_mode, uint32_t ul_fws)
00096 {
00097 efc_write_fmr(p_efc, ul_access_mode | EEFC_FMR_FWS(ul_fws));
00098 return EFC_RC_OK;
00099 }
00100
00106 void efc_enable_frdy_interrupt(Efc *p_efc)
00107 {
00108 uint32_t ul_fmr = p_efc->EEFC_FMR;
00109
00110 efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_FRDY);
00111 }
00112
00118 void efc_disable_frdy_interrupt(Efc *p_efc)
00119 {
00120 uint32_t ul_fmr = p_efc->EEFC_FMR;
00121
00122 efc_write_fmr(p_efc, ul_fmr & (~EEFC_FMR_FRDY));
00123 }
00124
00131 void efc_set_flash_access_mode(Efc *p_efc, uint32_t ul_mode)
00132 {
00133 uint32_t ul_fmr = p_efc->EEFC_FMR & (~EEFC_FMR_FAM);
00134
00135 efc_write_fmr(p_efc, ul_fmr | ul_mode);
00136 }
00137
00145 uint32_t efc_get_flash_access_mode(Efc *p_efc)
00146 {
00147 return (p_efc->EEFC_FMR & EEFC_FMR_FAM);
00148 }
00149
00156 void efc_set_wait_state(Efc *p_efc, uint32_t ul_fws)
00157 {
00158 uint32_t ul_fmr = p_efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk);
00159
00160 efc_write_fmr(p_efc, ul_fmr | EEFC_FMR_FWS(ul_fws));
00161 }
00162
00170 uint32_t efc_get_wait_state(Efc *p_efc)
00171 {
00172 return ((p_efc->EEFC_FMR & EEFC_FMR_FWS_Msk) >> EEFC_FMR_FWS_Pos);
00173 }
00174
00188 uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
00189 uint32_t ul_argument)
00190 {
00191
00192 if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
00193 return EFC_RC_NOT_SUPPORT;
00194 }
00195
00196
00197 static uint32_t(*iap_perform_command) (uint32_t, uint32_t);
00198 uint32_t ul_efc_nb = (p_efc == EFC0) ? 0 : 1;
00199
00200 iap_perform_command =
00201 (uint32_t(*)(uint32_t, uint32_t))
00202 *((uint32_t *) CHIP_FLASH_IAP_ADDRESS);
00203 iap_perform_command(ul_efc_nb,
00204 EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(ul_argument) |
00205 EEFC_FCR_FCMD(ul_command));
00206 return (p_efc->EEFC_FSR & EEFC_ERROR_FLAGS);
00207 }
00208
00218 uint32_t efc_get_status(Efc *p_efc)
00219 {
00220 return p_efc->EEFC_FSR;
00221 }
00222
00230 uint32_t efc_get_result(Efc *p_efc)
00231 {
00232 return p_efc->EEFC_FRR;
00233 }
00234
00247 RAMFUNC
00248 uint32_t efc_perform_read_sequence(Efc *p_efc,
00249 uint32_t ul_cmd_st, uint32_t ul_cmd_sp,
00250 uint32_t *p_ul_buf, uint32_t ul_size)
00251 {
00252 volatile uint32_t ul_status;
00253 uint32_t ul_cnt;
00254
00255 uint32_t *p_ul_data =
00256 (uint32_t *) ((p_efc == EFC0) ?
00257 READ_BUFF_ADDR0 : READ_BUFF_ADDR1);
00258
00259 if (p_ul_buf == NULL) {
00260 return EFC_RC_INVALID;
00261 }
00262
00263 p_efc->EEFC_FMR |= (0x1u << 16);
00264
00265
00266
00267 p_efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(0)
00268 | EEFC_FCR_FCMD(ul_cmd_st);
00269
00270
00271
00272 do {
00273 ul_status = p_efc->EEFC_FSR;
00274 } while ((ul_status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
00275
00276
00277
00278
00279 for (ul_cnt = 0; ul_cnt < ul_size; ul_cnt++) {
00280 p_ul_buf[ul_cnt] = p_ul_data[ul_cnt];
00281 }
00282
00283
00284 p_efc->EEFC_FCR =
00285 EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(0) |
00286 EEFC_FCR_FCMD(ul_cmd_sp);
00287
00288
00289
00290 do {
00291 ul_status = p_efc->EEFC_FSR;
00292 } while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
00293
00294 p_efc->EEFC_FMR &= ~(0x1u << 16);
00295
00296 return EFC_RC_OK;
00297 }
00298
00305 RAMFUNC
00306 void efc_write_fmr(Efc *p_efc, uint32_t ul_fmr)
00307 {
00308 p_efc->EEFC_FMR = ul_fmr;
00309 }
00310
00319 RAMFUNC
00320 uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
00321 {
00322 volatile uint32_t ul_status;
00323
00324 p_efc->EEFC_FCR = ul_fcr;
00325 do {
00326 ul_status = p_efc->EEFC_FSR;
00327 } while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
00328
00329 return (ul_status & EEFC_ERROR_FLAGS);
00330 }
00331
00333
00335
00336 #ifdef __cplusplus
00337 }
00338 #endif
00339
00340