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
00063 #include <cfg/os.h>
00064 #include <cfg/memory.h>
00065
00066 #include <sys/event.h>
00067 #include <sys/timer.h>
00068
00069 #include <stdlib.h>
00070 #include <string.h>
00071
00072 #include <dev/at49bv.h>
00073
00076 #ifndef FLASH_CHIP_BASE
00077 #define FLASH_CHIP_BASE 0x10000000
00078 #endif
00079
00082 #ifndef FLASH_CONF_SECTOR
00083 #define FLASH_CONF_SECTOR 0x6000
00084 #endif
00085
00093 #ifndef FLASH_CONF_SIZE
00094 #define FLASH_CONF_SIZE 512
00095 #endif
00096
00097 #ifndef FLASH_ERASE_WAIT
00098 #define FLASH_ERASE_WAIT 3000
00099 #endif
00100
00101 #ifndef FLASH_CHIP_ERASE_WAIT
00102 #define FLASH_CHIP_ERASE_WAIT 50000
00103 #endif
00104
00105 #ifndef FLASH_WRITE_POLLS
00106 #define FLASH_WRITE_POLLS 1000
00107 #endif
00108
00109
00110 #ifdef FLASH_8BIT
00111 typedef unsigned char flashdat_t;
00112 #else
00113 typedef unsigned short flashdat_t;
00114 #endif
00115
00116 typedef unsigned long flashadr_t;
00117 typedef volatile flashdat_t *flashptr_t;
00118
00119 static flashptr_t chip = (flashptr_t) FLASH_CHIP_BASE;
00120
00121 #define FLASH_UNLOCK(base) { \
00122 base[0x0555] = 0xAA; \
00123 base[0x0AAA] = 0x55; \
00124 }
00125
00126 #define FLASH_COMMAND(base, cmd) { \
00127 base[0x0555] = cmd; \
00128 }
00129
00130 #define FLASH_CMD_ERASE 0x80
00131 #define FLASH_CMD_ERASE_CHIP 0x10
00132 #define FLASH_CMD_ERASE_SECTOR 0x30
00133
00134 #define FLASH_CMD_ENTER_ID 0x90
00135 #define FLASH_CMD_EXIT_ID 0xF0
00136
00137 #define FLASH_CMD_PROGRAM 0xA0
00138
00144 static int At49bvWaitReady(flashptr_t addr, flashdat_t data, uint32_t tmo, int poll)
00145 {
00146 while (*addr != data) {
00147 if (!poll) {
00148 NutSleep(1);
00149 }
00150 if (tmo-- == 0) {
00151 return -1;
00152 }
00153 }
00154 return 0;
00155 }
00156
00157
00158
00159
00160 unsigned long At49bvInit(void)
00161 {
00162 unsigned long id;
00163
00164 FLASH_UNLOCK(chip);
00165 FLASH_COMMAND(chip, FLASH_CMD_ENTER_ID);
00166 id = chip[0];
00167 id <<= 16;
00168 id |= chip[1];
00169 FLASH_UNLOCK(chip);
00170 FLASH_COMMAND(chip, FLASH_CMD_EXIT_ID);
00171
00172 return id;
00173 }
00174
00181 unsigned long long AT49bvReadProtectionRegister(int factory)
00182 {
00183 unsigned long long id;
00184
00185 FLASH_UNLOCK(chip);
00186 FLASH_COMMAND(chip, FLASH_CMD_ENTER_ID);
00187 if (factory) {
00188 id = chip[0x81];
00189 id <<= 16;
00190 id |= chip[0x82];
00191 id <<= 16;
00192 id |= chip[0x83];
00193 id <<= 16;
00194 id |= chip[0x84];
00195 } else {
00196 id = chip[0x85];
00197 id <<= 16;
00198 id |= chip[0x86];
00199 id <<= 16;
00200 id |= chip[0x87];
00201 id <<= 16;
00202 id |= chip[0x88];
00203 }
00204 FLASH_UNLOCK(chip);
00205 FLASH_COMMAND(chip, FLASH_CMD_EXIT_ID);
00206
00207 return id;
00208 }
00209
00213 int At49bvSectorErase(u_int off)
00214 {
00215 flashptr_t ptr = (flashptr_t) (uptr_t) (FLASH_CHIP_BASE + off);
00216
00217 FLASH_UNLOCK(chip);
00218 FLASH_COMMAND(chip, FLASH_CMD_ERASE);
00219 FLASH_UNLOCK(chip);
00220 *ptr = FLASH_CMD_ERASE_SECTOR;
00221
00222 return At49bvWaitReady(ptr, (flashdat_t) - 1, FLASH_ERASE_WAIT, 0);
00223 }
00224
00228 int At49bvChipErase(void)
00229 {
00230 FLASH_UNLOCK(chip);
00231 FLASH_COMMAND(chip, FLASH_CMD_ERASE);
00232 FLASH_UNLOCK(chip);
00233 FLASH_COMMAND(chip, FLASH_CMD_ERASE_CHIP);
00234
00235 return At49bvWaitReady(chip, (flashdat_t) - 1, FLASH_CHIP_ERASE_WAIT, 0);
00236 }
00237
00247 int At49bvSectorRead(u_int off, void *data, u_int len)
00248 {
00249 memcpy(data, (void *) (uptr_t) (FLASH_CHIP_BASE + off), len);
00250
00251 return 0;
00252 }
00253
00265 int At49bvSectorWrite(u_int off, CONST void *data, u_int len)
00266 {
00267 int rc = 0;
00268 flashptr_t sp = (flashptr_t) data;
00269 flashptr_t dp = (flashptr_t) (uptr_t) (FLASH_CHIP_BASE + off);
00270 u_int i;
00271
00272 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00273
00274 if (*sp != (flashdat_t) - 1) {
00275
00276 FLASH_UNLOCK(chip);
00277 FLASH_COMMAND(chip, FLASH_CMD_PROGRAM);
00278 *dp = *sp;
00279 if ((rc = At49bvWaitReady(dp, *sp, FLASH_WRITE_POLLS, 1)) != 0) {
00280 break;
00281 }
00282 }
00283 dp++;
00284 sp++;
00285 }
00286 return rc;
00287 }
00288
00298 int At49bvParamRead(u_int pos, void *data, u_int len)
00299 {
00300 return At49bvSectorRead(FLASH_CONF_SECTOR + pos, data, len);
00301 }
00302
00312 int At49bvParamWrite(u_int pos, CONST void *data, u_int len)
00313 {
00314 int rc = -1;
00315 uint8_t *buff;
00316
00317
00318 if ((buff = malloc(FLASH_CONF_SIZE)) != 0) {
00319 rc = At49bvSectorRead(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00320
00321 if (memcmp(buff + pos, data, len)) {
00322
00323 memcpy(buff + pos, data, len);
00324
00325 if ((rc = At49bvSectorErase(FLASH_CONF_SECTOR)) == 0) {
00326 rc = At49bvSectorWrite(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00327 }
00328 }
00329 free(buff);
00330 }
00331 return rc;
00332 }