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
00067 #include <cfg/os.h>
00068 #include <cfg/memory.h>
00069
00070 #include <sys/event.h>
00071 #include <sys/timer.h>
00072
00073 #include <stdlib.h>
00074 #include <string.h>
00075
00076 #include <dev/at49bv.h>
00077
00080 #ifndef FLASH_CHIP_BASE
00081 #define FLASH_CHIP_BASE 0x10000000
00082 #endif
00083
00086 #ifndef FLASH_CONF_SECTOR
00087 #define FLASH_CONF_SECTOR 0x6000
00088 #endif
00089
00097 #ifndef FLASH_CONF_SIZE
00098 #define FLASH_CONF_SIZE 512
00099 #endif
00100
00101 #ifndef FLASH_ERASE_WAIT
00102 #define FLASH_ERASE_WAIT 3000
00103 #endif
00104
00105 #ifndef FLASH_CHIP_ERASE_WAIT
00106 #define FLASH_CHIP_ERASE_WAIT 50000
00107 #endif
00108
00109 #ifndef FLASH_WRITE_POLLS
00110 #define FLASH_WRITE_POLLS 1000
00111 #endif
00112
00113
00114 #ifdef FLASH_8BIT
00115 typedef unsigned char flashdat_t;
00116 #else
00117 typedef unsigned short flashdat_t;
00118 #endif
00119
00120 typedef unsigned long flashadr_t;
00121 typedef volatile flashdat_t *flashptr_t;
00122
00123 static flashptr_t chip = (flashptr_t) FLASH_CHIP_BASE;
00124
00125 #define FLASH_UNLOCK(base) { \
00126 base[0x0555] = 0xAA; \
00127 base[0x0AAA] = 0x55; \
00128 }
00129
00130 #define FLASH_COMMAND(base, cmd) { \
00131 base[0x0555] = cmd; \
00132 }
00133
00134 #define FLASH_CMD_ERASE 0x80
00135 #define FLASH_CMD_ERASE_CHIP 0x10
00136 #define FLASH_CMD_ERASE_SECTOR 0x30
00137
00138 #define FLASH_CMD_ENTER_ID 0x90
00139 #define FLASH_CMD_EXIT_ID 0xF0
00140
00141 #define FLASH_CMD_PROGRAM 0xA0
00142
00148 static int At49bvWaitReady(flashptr_t addr, flashdat_t data, uint32_t tmo, int poll)
00149 {
00150 while (*addr != data) {
00151 if (!poll) {
00152 NutSleep(1);
00153 }
00154 if (tmo-- == 0) {
00155 return -1;
00156 }
00157 }
00158 return 0;
00159 }
00160
00161
00162
00163
00164 unsigned long At49bvInit(void)
00165 {
00166 unsigned long id;
00167
00168 FLASH_UNLOCK(chip);
00169 FLASH_COMMAND(chip, FLASH_CMD_ENTER_ID);
00170 id = chip[0];
00171 id <<= 16;
00172 id |= chip[1];
00173 FLASH_UNLOCK(chip);
00174 FLASH_COMMAND(chip, FLASH_CMD_EXIT_ID);
00175
00176 return id;
00177 }
00178
00185 unsigned long long AT49bvReadProtectionRegister(int factory)
00186 {
00187 unsigned long long id;
00188
00189 FLASH_UNLOCK(chip);
00190 FLASH_COMMAND(chip, FLASH_CMD_ENTER_ID);
00191 if (factory) {
00192 id = chip[0x81];
00193 id <<= 16;
00194 id |= chip[0x82];
00195 id <<= 16;
00196 id |= chip[0x83];
00197 id <<= 16;
00198 id |= chip[0x84];
00199 } else {
00200 id = chip[0x85];
00201 id <<= 16;
00202 id |= chip[0x86];
00203 id <<= 16;
00204 id |= chip[0x87];
00205 id <<= 16;
00206 id |= chip[0x88];
00207 }
00208 FLASH_UNLOCK(chip);
00209 FLASH_COMMAND(chip, FLASH_CMD_EXIT_ID);
00210
00211 return id;
00212 }
00213
00217 int At49bvSectorErase(unsigned int off)
00218 {
00219 flashptr_t ptr = (flashptr_t) (uintptr_t) (FLASH_CHIP_BASE + off);
00220
00221 FLASH_UNLOCK(chip);
00222 FLASH_COMMAND(chip, FLASH_CMD_ERASE);
00223 FLASH_UNLOCK(chip);
00224 *ptr = FLASH_CMD_ERASE_SECTOR;
00225
00226 return At49bvWaitReady(ptr, (flashdat_t) - 1, FLASH_ERASE_WAIT, 0);
00227 }
00228
00232 int At49bvChipErase(void)
00233 {
00234 FLASH_UNLOCK(chip);
00235 FLASH_COMMAND(chip, FLASH_CMD_ERASE);
00236 FLASH_UNLOCK(chip);
00237 FLASH_COMMAND(chip, FLASH_CMD_ERASE_CHIP);
00238
00239 return At49bvWaitReady(chip, (flashdat_t) - 1, FLASH_CHIP_ERASE_WAIT, 0);
00240 }
00241
00251 int At49bvSectorRead(unsigned int off, void *data, unsigned int len)
00252 {
00253 memcpy(data, (void *) (uintptr_t) (FLASH_CHIP_BASE + off), len);
00254
00255 return 0;
00256 }
00257
00269 int At49bvSectorWrite(unsigned int off, CONST void *data, unsigned int len)
00270 {
00271 int rc = 0;
00272 flashptr_t sp = (flashptr_t) data;
00273 flashptr_t dp = (flashptr_t) (uintptr_t) (FLASH_CHIP_BASE + off);
00274 unsigned int i;
00275
00276 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00277
00278 if (*sp != (flashdat_t) - 1) {
00279
00280 FLASH_UNLOCK(chip);
00281 FLASH_COMMAND(chip, FLASH_CMD_PROGRAM);
00282 *dp = *sp;
00283 if ((rc = At49bvWaitReady(dp, *sp, FLASH_WRITE_POLLS, 1)) != 0) {
00284 break;
00285 }
00286 }
00287 dp++;
00288 sp++;
00289 }
00290 return rc;
00291 }
00292
00302 int At49bvParamRead(unsigned int pos, void *data, unsigned int len)
00303 {
00304 return At49bvSectorRead(FLASH_CONF_SECTOR + pos, data, len);
00305 }
00306
00316 int At49bvParamWrite(unsigned int pos, CONST void *data, unsigned int len)
00317 {
00318 int rc = -1;
00319 uint8_t *buff;
00320
00321
00322 if ((buff = malloc(FLASH_CONF_SIZE)) != 0) {
00323 rc = At49bvSectorRead(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00324
00325 if (memcmp(buff + pos, data, len)) {
00326
00327 memcpy(buff + pos, data, len);
00328
00329 if ((rc = At49bvSectorErase(FLASH_CONF_SECTOR)) == 0) {
00330 rc = At49bvSectorWrite(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00331 }
00332 }
00333 free(buff);
00334 }
00335 return rc;
00336 }