at91_efc.c
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 <sys/atom.h>
00060 #include <dev/nvmem.h>
00061
00062 #include <stdint.h>
00063 #include <stdlib.h>
00064 #include <string.h>
00065
00066 #include <arch/arm/at91_efc.h>
00067
00072
00075 #ifndef FLASH_CHIP_BASE
00076 #define FLASH_CHIP_BASE 0x00100000
00077 #endif
00078
00081 #ifndef FLASH_CONF_SECTOR
00082 #define FLASH_CONF_SECTOR 0x0003FF00
00083 #endif
00084
00094 #ifndef FLASH_CONF_SIZE
00095 #define FLASH_CONF_SIZE 256
00096 #endif
00097
00098 #ifndef FLASH_WRITE_WAIT
00099 #define FLASH_WRITE_WAIT 60000
00100 #endif
00101
00102 #ifndef FLASH_ERASE_WAIT
00103 #define FLASH_ERASE_WAIT 60000
00104 #endif
00105
00106 #ifndef FLASH_CHIP_ERASE_WAIT
00107 #define FLASH_CHIP_ERASE_WAIT 600000
00108 #endif
00109
00110
00111 typedef uint32_t flashdat_t;
00112 typedef unsigned long flashadr_t;
00113 typedef volatile flashdat_t *flashptr_t;
00114
00121 RAMFUNC int At91EfcCmd(unsigned int cmd, uint32_t tmo)
00122 {
00123 int rc = 0;
00124 unsigned int fsr;
00125
00126
00127 while ((inr(MC_FSR) & MC_FRDY) == 0) {
00128 if (tmo && --tmo < 1) {
00129 return -1;
00130 }
00131 }
00132
00133
00134 NutEnterCritical();
00135
00136
00137 outr(MC_FCR, MC_KEY | cmd);
00138
00139
00140 while (((fsr = inr(MC_FSR)) & MC_FRDY) == 0) {
00141 if (tmo && --tmo < 1) {
00142 rc = -1;
00143 break;
00144 }
00145 }
00146
00147
00148 NutExitCritical();
00149
00150
00151 if (fsr & (MC_LOCKE | MC_PROGE)) {
00152 rc = -1;
00153 }
00154 return rc;
00155 }
00156
00166 int At91EfcSectorRead(unsigned int off, void *data, unsigned int len)
00167 {
00168 memcpy(data, (void *) (uptr_t) (FLASH_CHIP_BASE + off), len);
00169
00170 return 0;
00171 }
00172
00185 int At91EfcSectorWrite(unsigned int off, CONST void *data, unsigned int len)
00186 {
00187 flashptr_t dp = (flashptr_t) (uptr_t) (FLASH_CHIP_BASE + off);
00188 int rc;
00189 unsigned int i;
00190
00191 if (data) {
00192 flashptr_t sp = (flashptr_t) data;
00193
00194
00195 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00196 *dp++ = *sp++;
00197 }
00198 }
00199 else {
00200
00201 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00202 *dp++ = (flashdat_t)(-1);
00203 }
00204 }
00205
00206
00207 outr(MC_FMR, (i = inr(MC_FMR)) & ~MC_NEBP);
00208
00209 rc = At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_WP, FLASH_WRITE_WAIT);
00210
00211 outr(MC_FMR, i);
00212
00213 return rc;
00214 }
00215
00219 int At91EfcSectorErase(unsigned int off)
00220 {
00221 return At91EfcSectorWrite(off, NULL, 256);
00222 }
00223
00231 int At91EfcRegionLock(unsigned int off)
00232 {
00233 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_SLB, FLASH_WRITE_WAIT);
00234 }
00235
00243 int At91EfcRegionUnlock(unsigned int off)
00244 {
00245 return At91EfcCmd((off & MC_PAGEN_MASK) | MC_FCMD_CLB, FLASH_WRITE_WAIT);
00246 }
00247
00259 int At91EfcParamRead(unsigned int pos, void *data, unsigned int len)
00260 {
00261 return At91EfcSectorRead(FLASH_CONF_SECTOR + pos, data, len);
00262 }
00263
00278 int At91EfcParamWrite(unsigned int pos, CONST void *data, unsigned int len)
00279 {
00280 int rc = -1;
00281 uint8_t *buff;
00282
00283
00284 if ((buff = malloc(FLASH_CONF_SIZE)) != NULL) {
00285
00286 rc = At91EfcSectorRead(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00287
00288 if (memcmp(buff + pos, data, len)) {
00289
00290 memcpy(buff + pos, data, len);
00291
00292 if (At91EfcRegionUnlock(FLASH_CONF_SECTOR) == 0) {
00293 rc = At91EfcSectorWrite(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00294 At91EfcRegionLock(FLASH_CONF_SECTOR);
00295 }
00296 }
00297 free(buff);
00298 }
00299 return rc;
00300 }
00301