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
00055 #include <sys/atom.h>
00056 #include <dev/nvmem.h>
00057
00058 #include <stdint.h>
00059 #include <stdlib.h>
00060 #include <string.h>
00061
00062 #include <arch/arm/at91_efc.h>
00063
00068
00071 #ifndef FLASH_CHIP_BASE
00072 #define FLASH_CHIP_BASE 0x00100000
00073 #endif
00074
00077 #ifndef FLASH_CONF_SECTOR
00078 #define FLASH_CONF_SECTOR 0x0003FF00
00079 #endif
00080
00090 #ifndef FLASH_CONF_SIZE
00091 #define FLASH_CONF_SIZE 256
00092 #endif
00093
00094 #ifndef FLASH_WRITE_WAIT
00095 #define FLASH_WRITE_WAIT 60000
00096 #endif
00097
00098 #ifndef FLASH_ERASE_WAIT
00099 #define FLASH_ERASE_WAIT 60000
00100 #endif
00101
00102 #ifndef FLASH_CHIP_ERASE_WAIT
00103 #define FLASH_CHIP_ERASE_WAIT 600000
00104 #endif
00105
00106
00107 typedef uint32_t flashdat_t;
00108 typedef unsigned long flashadr_t;
00109 typedef volatile flashdat_t *flashptr_t;
00110
00117 RAMFUNC int At91EfcCmd(u_int cmd, uint32_t tmo)
00118 {
00119 int rc = 0;
00120 u_int fsr;
00121
00122
00123 while ((inr(MC_FSR) & MC_FRDY) == 0) {
00124 if (tmo && --tmo < 1) {
00125 return -1;
00126 }
00127 }
00128
00129
00130 NutEnterCritical();
00131
00132
00133 outr(MC_FCR, MC_KEY | cmd);
00134
00135
00136 while (((fsr = inr(MC_FSR)) & MC_FRDY) == 0) {
00137 if (tmo && --tmo < 1) {
00138 rc = -1;
00139 break;
00140 }
00141 }
00142
00143
00144 NutExitCritical();
00145
00146
00147 if (fsr & (MC_LOCKE | MC_PROGE)) {
00148 rc = -1;
00149 }
00150 return rc;
00151 }
00152
00162 int At91EfcSectorRead(u_int off, void *data, u_int len)
00163 {
00164 memcpy(data, (void *) (uptr_t) (FLASH_CHIP_BASE + off), len);
00165
00166 return 0;
00167 }
00168
00181 int At91EfcSectorWrite(u_int off, CONST void *data, u_int len)
00182 {
00183 flashptr_t dp = (flashptr_t) (uptr_t) (FLASH_CHIP_BASE + off);
00184 int rc;
00185 u_int i;
00186
00187 if (data) {
00188 flashptr_t sp = (flashptr_t) data;
00189
00190
00191 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00192 *dp++ = *sp++;
00193 }
00194 }
00195 else {
00196
00197 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00198 *dp++ = (flashdat_t)(-1);
00199 }
00200 }
00201
00202
00203 outr(MC_FMR, (i = inr(MC_FMR)) & ~MC_NEBP);
00204
00205 rc = At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_WP, FLASH_WRITE_WAIT);
00206
00207 outr(MC_FMR, i);
00208
00209 return rc;
00210 }
00211
00215 int At91EfcSectorErase(u_int off)
00216 {
00217 return At91EfcSectorWrite(off, NULL, 256);
00218 }
00219
00227 int At91EfcRegionLock(u_int off)
00228 {
00229 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_SLB, FLASH_WRITE_WAIT);
00230 }
00231
00239 int At91EfcRegionUnlock(u_int off)
00240 {
00241 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_CLB, FLASH_WRITE_WAIT);
00242 }
00243
00255 int At91EfcParamRead(u_int pos, void *data, u_int len)
00256 {
00257 return At91EfcSectorRead(FLASH_CONF_SECTOR + pos, data, len);
00258 }
00259
00274 int At91EfcParamWrite(u_int pos, CONST void *data, u_int len)
00275 {
00276 int rc = -1;
00277 uint8_t *buff;
00278
00279
00280 if ((buff = malloc(FLASH_CONF_SIZE)) != NULL) {
00281
00282 rc = At91EfcSectorRead(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00283
00284 if (memcmp(buff + pos, data, len)) {
00285
00286 memcpy(buff + pos, data, len);
00287
00288 if (At91EfcRegionUnlock(FLASH_CONF_SECTOR) == 0) {
00289 rc = At91EfcSectorWrite(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00290 At91EfcRegionLock(FLASH_CONF_SECTOR);
00291 }
00292 }
00293 free(buff);
00294 }
00295 return rc;
00296 }
00297