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
00034
00062 #include <cfg/os.h>
00063 #include <cfg/memory.h>
00064
00065 #include <sys/timer.h>
00066
00067 #include <string.h>
00068 #include <stdlib.h>
00069
00070 #include <dev/at91_spi.h>
00071 #include <dev/at45db.h>
00072
00073 #ifndef MAX_AT45_DEVICES
00074 #define MAX_AT45_DEVICES 1
00075 #endif
00076
00077 #ifndef MAX_AT45_CMDLEN
00078 #define MAX_AT45_CMDLEN 8
00079 #endif
00080
00081 #ifndef AT45_CONF_DFSPI
00082 #define AT45_CONF_DFSPI SPI0_BASE
00083 #endif
00084
00085 #ifndef AT45_CONF_DFPCS
00086 #define AT45_CONF_DFPCS 1
00087 #endif
00088
00089 #ifndef AT45_ERASE_WAIT
00090 #define AT45_ERASE_WAIT 3000
00091 #endif
00092
00093 #ifndef AT45_CHIP_ERASE_WAIT
00094 #define AT45_CHIP_ERASE_WAIT 50000
00095 #endif
00096
00097 #ifndef AT45_WRITE_POLLS
00098 #define AT45_WRITE_POLLS 1000
00099 #endif
00100
00111 #define DFCMD_CONT_READ_LF 0x03
00112
00118 #define DFCMD_CONT_READ_HF 0x0B
00119
00121 #define DFCMD_BLOCK_ERASE 0x50
00122
00124 #define DFCMD_SECTOR_ERASE 0x7C
00125
00127 #define DFCMD_PAGE_ERASE 0x81
00128
00130 #define DFCMD_BUF1_PROG 0x82
00131
00133 #define DFCMD_BUF1_FLASH 0x83
00134
00136 #define DFCMD_BUF1_WRITE 0x84
00137
00139 #define DFCMD_BUF2_PROG 0x85
00140
00142 #define DFCMD_BUF2_FLASH 0x86
00143
00145 #define DFCMD_BUF2_WRITE 0x87
00146
00148 #define DFCMD_BUF1_FLASH_NE 0x88
00149
00151 #define DFCMD_BUF2_FLASH_NE 0x89
00152
00154 #define DFCMD_CHIP_ERASE 0xC7
00155
00157 #define DFCMD_BUF1_READ_LF 0xD1
00158
00163 #define DFCMD_READ_PAGE 0xD2
00164
00166 #define DFCMD_BUF2_READ_LF 0xD3
00167
00169 #define DFCMD_BUF1_READ 0xD4
00170
00172 #define DFCMD_BUF2_READ 0xD6
00173
00175 #define DFCMD_READ_STATUS 0xD7
00176
00182 #define DFCMD_CONT_READ 0xE8
00183
00185 #define AT45DB_AT91
00186
00187
00188 #if defined(AT45DB_SPI0_DEVICE)
00189
00190 #include <dev/sppif0.h>
00191 #if defined(AT45DB_RESET_ACTIVE_HIGH)
00192 #define SpiReset(act) Sppi0ChipReset(AT45DB_SPI0_DEVICE, act)
00193 #else
00194 #define SpiReset(act) Sppi0ChipReset(AT45DB_SPI0_DEVICE, !act)
00195 #endif
00196 #define SpiSetMode() Sppi0SetMode(AT45DB_SPI0_DEVICE, AT45DB_SPI_MODE)
00197 #define SpiSetSpeed() Sppi0SetSpeed(AT45DB_SPI0_DEVICE, AT45DB_SPI_RATE)
00198 #if defined(AT45DB_SELECT_ACTIVE_HIGH)
00199 #define SpiSelect() Sppi0SelectDevice(AT45DB_SPI0_DEVICE)
00200 #define SpiDeselect() Sppi0DeselectDevice(AT45DB_SPI0_DEVICE)
00201 #else
00202 #define SpiSelect() Sppi0NegSelectDevice(AT45DB_SPI0_DEVICE)
00203 #define SpiDeselect() Sppi0NegDeselectDevice(AT45DB_SPI0_DEVICE)
00204 #endif
00205 #define SpiByte Sppi0Byte
00206
00207 #elif defined(AT45DB_SBBI0_DEVICE)
00208
00209 #include <dev/sbbif0.h>
00210 #if defined(VS10XX_RESET_ACTIVE_HIGH)
00211 #define SpiReset(act) Sbbi0ChipReset(AT45DB_SBBI0_DEVICE, act)
00212 #else
00213 #define SpiReset(act) Sbbi0ChipReset(AT45DB_SBBI0_DEVICE, !act)
00214 #endif
00215 #define SpiSetMode() Sbbi0SetMode(AT45DB_SBBI0_DEVICE, AT45DB_SPI_MODE)
00216 #define SpiSetSpeed() Sbbi0SetSpeed(AT45DB_SBBI0_DEVICE, AT45DB_SPI_RATE)
00217 #if defined(VS10XX_SELECT_ACTIVE_HIGH)
00218 #define SpiSelect() Sbbi0SelectDevice(AT45DB_SBBI0_DEVICE)
00219 #define SpiDeselect() Sbbi0DeselectDevice(AT45DB_SBBI0_DEVICE)
00220 #else
00221 #define SpiSelect() Sbbi0NegSelectDevice(AT45DB_SBBI0_DEVICE)
00222 #define SpiDeselect() Sbbi0NegDeselectDevice(AT45DB_SBBI0_DEVICE)
00223 #endif
00224 #define SpiByte Sbbi0Byte
00225
00226 #endif
00227
00231 typedef struct _AT45_DEVTAB {
00232 u_long devt_pages;
00233 u_int devt_pagsiz;
00234 u_int devt_offs;
00235 u_char devt_srmsk;
00236 u_char devt_srval;
00237 } AT45_DEVTAB;
00238
00242 typedef struct _AT45DB_DCB {
00243 AT45_DEVTAB *dcb_devt;
00244 u_int dcb_spibas;
00245 u_int dcb_spipcs;
00246 u_char dcb_cmdbuf[MAX_AT45_CMDLEN];
00247 } AT45DB_DCB;
00248
00252 AT45_DEVTAB at45_devt[] = {
00253 {512, 264, 9, 0x3C, 0x0C},
00254 {1025, 264, 9, 0x3C, 0x14},
00255 {2048, 264, 9, 0x3C, 0x1C},
00256 {4096, 264, 9, 0x3C, 0x24},
00257 {4096, 528, 10, 0x3C, 0x2C},
00258 {8192, 528, 10, 0x3C, 0x34},
00259 {8192, 1056, 11, 0x38, 0x38},
00260 {0, 0, 0, 0, 0}
00261 };
00262
00266 static AT45DB_DCB dcbtab[MAX_AT45_DEVICES];
00267
00268
00269 static int dcbnum;
00270
00271
00272 static int dd_param = -1;
00273
00285 int At45dbSendCmd(int dd, u_char op, u_long parm, int len, CONST void *tdata, void *rdata, int datalen)
00286 {
00287 u_char *cb = dcbtab[dd].dcb_cmdbuf;
00288
00289 if (len > MAX_AT45_CMDLEN) {
00290 return -1;
00291 }
00292 memset(cb, 0, len);
00293 cb[0] = op;
00294 if (parm) {
00295 cb[1] = (u_char) (parm >> 16);
00296 cb[2] = (u_char) (parm >> 8);
00297 cb[3] = (u_char) parm;
00298 }
00299 return At91SpiTransfer2(dcbtab[dd].dcb_spibas, dcbtab[dd].dcb_spipcs, cb, cb, len, tdata, rdata, datalen);
00300 }
00301
00302 u_char At45dbGetStatus(int dd)
00303 {
00304 u_char buf[2] = { DFCMD_READ_STATUS, 0xFF };
00305
00306 if (At91SpiTransfer2(dcbtab[dd].dcb_spibas, dcbtab[dd].dcb_spipcs, buf, buf, 2, NULL, NULL, 0)) {
00307 return (u_char) - 1;
00308 }
00309 return buf[1];
00310 }
00311
00317 int At45dbWaitReady(int dd, u_long tmo, int poll)
00318 {
00319 u_char sr;
00320
00321 while (((sr = At45dbGetStatus(dd)) & 0x80) == 0) {
00322 if (!poll) {
00323 NutSleep(1);
00324 }
00325 if (tmo-- == 0) {
00326 return -1;
00327 }
00328 }
00329 return 0;
00330 }
00331
00341 int At45dbInit(u_int spibas, u_int spipcs)
00342 {
00343 int dd = -1;
00344 u_char sr;
00345 int i;
00346
00347 for (i = 0; i < dcbnum; i++) {
00348 if (dcbtab[i].dcb_spibas == spibas && dcbtab[i].dcb_spipcs == spipcs) {
00349 return i;
00350 }
00351 }
00352
00353 if (dcbnum >= MAX_AT45_DEVICES) {
00354 return -1;
00355 }
00356
00357 #if defined(MCU_AT91SAM7X256) || defined(MCU_AT91SAM9260)
00358 At91SpiInit(spibas);
00359 At91SpiReset(spibas);
00360 At91SpiInitChipSelects(spibas, _BV(spipcs));
00361 At91SpiSetRate(spibas, spipcs, 1000000);
00362 At91SpiSetModeFlags(spibas, spipcs, SPIMF_MASTER | SPIMF_SCKIAHI | SPIMF_CAPRISE);
00363 #elif defined(MCU_AT91R40008)
00364 #endif
00365
00366 dcbtab[dcbnum].dcb_spibas = spibas;
00367 dcbtab[dcbnum].dcb_spipcs = spipcs;
00368 sr = At45dbGetStatus(dcbnum);
00369
00370 for (i = 0; at45_devt[i].devt_pages; i++) {
00371 if ((sr & at45_devt[i].devt_srmsk) == at45_devt[i].devt_srval) {
00372 dcbtab[dcbnum].dcb_devt = &at45_devt[i];
00373 dd = dcbnum++;
00374 break;
00375 }
00376 }
00377 return dd;
00378 }
00379
00383 int At45dbPageErase(int dd, u_long pgn)
00384 {
00385 pgn <<= dcbtab[dd].dcb_devt->devt_offs;
00386 return At45dbSendCmd(dd, DFCMD_PAGE_ERASE, pgn, 4, NULL, NULL, 0);
00387 }
00388
00392 int At45dbChipErase(void)
00393 {
00394 return -1;
00395 }
00396
00407 int At45dbPageRead(int dd, u_long pgn, void *data, u_int len)
00408 {
00409 pgn <<= dcbtab[dd].dcb_devt->devt_offs;
00410 return At45dbSendCmd(dd, DFCMD_CONT_READ, pgn, 8, data, data, len);
00411 }
00412
00425 int At45dbPageWrite(int dd, u_long pgn, CONST void *data, u_int len)
00426 {
00427 int rc = -1;
00428 void *rp;
00429
00430 if ((rp = malloc(len)) != NULL) {
00431
00432 if (At45dbSendCmd(dd, DFCMD_BUF1_WRITE, 0, 4, data, rp, len) == 0) {
00433
00434 pgn <<= dcbtab[dd].dcb_devt->devt_offs;
00435 if (At45dbSendCmd(dd, DFCMD_BUF1_FLASH, pgn, 4, NULL, NULL, 0) == 0) {
00436 rc = At45dbWaitReady(dd, AT45_WRITE_POLLS, 1);
00437 }
00438 }
00439 free(rp);
00440 }
00441 return rc;
00442 }
00443
00444 u_long At45dbPages(int dd)
00445 {
00446 return dcbtab[dd].dcb_devt->devt_pages;
00447 }
00448
00449 u_int At45dbPageSize(int dd)
00450 {
00451 return dcbtab[dd].dcb_devt->devt_pagsiz;
00452 }
00453
00454 u_long At45dbParamPage(void)
00455 {
00456 #ifdef AT45_CONF_PAGE
00457 return AT45_CONF_PAGE;
00458 #else
00459 return dcbtab[dd_param].dcb_devt->devt_pages - 1;
00460 #endif
00461 }
00462
00474 int At45dbParamSize(void)
00475 {
00476 int rc;
00477
00478 if (dd_param == -1 && (dd_param = At45dbInit(AT45_CONF_DFSPI, AT45_CONF_DFPCS)) == -1) {
00479 return -1;
00480 }
00481 #ifdef AT45_CONF_SIZE
00482 rc = AT45_CONF_SIZE;
00483 #else
00484 rc = dcbtab[dd_param].dcb_devt->devt_pagsiz;
00485 #endif
00486 return rc;
00487 }
00488
00498 int At45dbParamRead(u_int pos, void *data, u_int len)
00499 {
00500 int rc = -1;
00501 u_char *buff;
00502 int csize = At45dbParamSize();
00503 u_long cpage = At45dbParamPage();
00504
00505
00506 if (csize > len && (buff = malloc(csize)) != NULL) {
00507 rc = At45dbPageRead(dd_param, cpage, buff, csize);
00508
00509 memcpy(data, buff + pos, len);
00510 free(buff);
00511 }
00512 return rc;
00513 }
00514
00524 int At45dbParamWrite(u_int pos, CONST void *data, u_int len)
00525 {
00526 int rc = -1;
00527 u_char *buff;
00528 int csize = At45dbParamSize();
00529 u_long cpage = At45dbParamPage();
00530
00531
00532 if (csize > len && (buff = malloc(csize)) != NULL) {
00533 rc = At45dbPageRead(dd_param, cpage, buff, csize);
00534
00535 if (memcmp(buff + pos, data, len)) {
00536
00537 memcpy(buff + pos, data, len);
00538
00539 rc = At45dbPageWrite(dd_param, cpage, buff, csize);
00540 }
00541 free(buff);
00542 }
00543 return rc;
00544 }