Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00059 #include <cfg/memory.h>
00060
00061 #include <sys/atom.h>
00062 #include <dev/nvmem.h>
00063
00064 #include <stdint.h>
00065 #include <stdlib.h>
00066 #include <string.h>
00067
00068 #include <arch/arm/atmel/at91_efc.h>
00069
00074
00077 #ifndef EFC_CHIP_BASE
00078 #define EFC_CHIP_BASE 0x00100000
00079 #endif
00080
00083 #ifndef EFC_CHIP_SIZE
00084 #define EFC_CHIP_SIZE 0x00040000
00085 #endif
00086
00095 #ifndef FLASH_CONF_SECTOR
00096 #if defined(MCU_AT91SAM7S512) || defined(MCU_AT91SAM7SE512) || \
00097 defined(MCU_AT91SAM7X512) || defined(MCU_AT91SAM9XE512)
00098 #define FLASH_CONF_SECTOR 0x0007FF00
00099 #else
00100 #define FLASH_CONF_SECTOR 0x0003FF00
00101 #endif
00102 #endif
00103
00113 #ifndef FLASH_CONF_SIZE
00114 #define FLASH_CONF_SIZE 256
00115 #endif
00116
00117 #ifndef EFC_WRITE_WAIT
00118 #define EFC_WRITE_WAIT 60000
00119 #endif
00120
00121 #ifndef EFC_ERASE_WAIT
00122 #define EFC_ERASE_WAIT 60000
00123 #endif
00124
00125 #ifndef EFC_CHIP_ERASE_WAIT
00126 #define EFC_CHIP_ERASE_WAIT 600000
00127 #endif
00128
00129
00130 typedef uint32_t flashdat_t;
00131 typedef unsigned long flashadr_t;
00132 typedef volatile flashdat_t *flashptr_t;
00133
00140 RAMFUNC int At91EfcCmdEx(int fci, unsigned int cmd, uint32_t tmo)
00141 {
00142 int rc = 0;
00143 unsigned int fsr;
00144
00145
00146 while ((inr(fci ? MC_FSR_EFC1: MC_FSR_EFC0) & MC_FRDY) == 0) {
00147 if (tmo && --tmo < 1) {
00148 return -1;
00149 }
00150 }
00151
00152
00153 NutEnterCritical();
00154
00155
00156 outr(fci ? MC_FCR_EFC1 : MC_FCR_EFC0, MC_KEY | cmd);
00157
00158
00159 while (((fsr = inr(fci ? MC_FSR_EFC1 : MC_FSR_EFC0)) & MC_FRDY) == 0) {
00160 if (tmo && --tmo < 1) {
00161 rc = -1;
00162 break;
00163 }
00164 }
00165
00166
00167 NutExitCritical();
00168
00169
00170 if (fsr & (MC_LOCKE | MC_PROGE)) {
00171 rc = -1;
00172 }
00173 return rc;
00174 }
00175
00182 RAMFUNC int At91EfcCmd(unsigned int cmd, uint32_t tmo)
00183 {
00184 return At91EfcCmdEx(0, cmd, tmo);
00185 }
00186
00196 int At91EfcSectorRead(unsigned int off, void *data, unsigned int len)
00197 {
00198 memcpy(data, (void *) (uptr_t) (EFC_CHIP_BASE + off), len);
00199
00200 return 0;
00201 }
00202
00215 int At91EfcSectorWrite(unsigned int off, CONST void *data, unsigned int len)
00216 {
00217 flashptr_t dp = (flashptr_t) (uptr_t) (EFC_CHIP_BASE + off);
00218 int rc;
00219 unsigned int i;
00220
00221 if (data) {
00222 flashptr_t sp = (flashptr_t) data;
00223
00224
00225 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00226 *dp++ = *sp++;
00227 }
00228 }
00229 else {
00230
00231 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00232 *dp++ = (flashdat_t)(-1);
00233 }
00234 }
00235
00236 if (off < EFC_CHIP_SIZE) {
00237
00238 outr(MC_FMR, (i = inr(MC_FMR)) & ~MC_NEBP);
00239
00240 rc = At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_WP, EFC_WRITE_WAIT);
00241
00242 outr(MC_FMR, i);
00243 } else {
00244
00245 outr(MC_FMR_EFC1, (i = inr(MC_FMR_EFC1)) & ~MC_NEBP);
00246
00247 rc = At91EfcCmdEx(1, ((off - EFC_CHIP_SIZE) & MC_PAGEN_MASK) | MC_FCMD_WP, EFC_WRITE_WAIT);
00248
00249 outr(MC_FMR_EFC1, i);
00250 }
00251 return rc;
00252 }
00253
00257 int At91EfcSectorErase(unsigned int off)
00258 {
00259 return At91EfcSectorWrite(off, NULL, 256);
00260 }
00261
00269 int At91EfcRegionLock(unsigned int off)
00270 {
00271 if (off < EFC_CHIP_SIZE) {
00272 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_SLB, EFC_WRITE_WAIT);
00273 }
00274 off -= EFC_CHIP_SIZE;
00275 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_SLB, EFC_WRITE_WAIT);
00276 }
00277
00285 int At91EfcRegionUnlock(unsigned int off)
00286 {
00287 if (off < EFC_CHIP_SIZE) {
00288 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_CLB, EFC_WRITE_WAIT);
00289 }
00290 off -= EFC_CHIP_SIZE;
00291 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_CLB, EFC_WRITE_WAIT);
00292 }
00293
00305 int At91EfcParamRead(unsigned int pos, void *data, unsigned int len)
00306 {
00307 return At91EfcSectorRead(FLASH_CONF_SECTOR + pos, data, len);
00308 }
00309
00324 int At91EfcParamWrite(unsigned int pos, CONST void *data, unsigned int len)
00325 {
00326 int rc = -1;
00327 uint8_t *buff;
00328
00329
00330 if ((buff = malloc(FLASH_CONF_SIZE)) != NULL) {
00331
00332 rc = At91EfcSectorRead(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00333
00334 if (memcmp(buff + pos, data, len)) {
00335
00336 memcpy(buff + pos, data, len);
00337
00338 if (At91EfcRegionUnlock(FLASH_CONF_SECTOR) == 0) {
00339 rc = At91EfcSectorWrite(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00340 At91EfcRegionLock(FLASH_CONF_SECTOR);
00341 }
00342 }
00343 free(buff);
00344 }
00345 return rc;
00346 }
00347