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