00001
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "conf_access.h"
00051
00052
00053 #if AT45DBX_MEM == ENABLE
00054
00055 #include "compiler.h"
00056 #include "board.h"
00057 #include "gpio.h"
00058 #include "spi.h"
00059 #include "conf_at45dbx.h"
00060 #include "at45dbx.h"
00061
00062
00063 #if AT45DBX_MEM_CNT > 4
00064 #error AT45DBX_MEM_CNT must not exceed 4
00065 #endif
00066
00067
00068
00069
00072
00073 #define AT45DBX_CMDA_RD_PAGE 0xD2
00074 #define AT45DBX_CMDA_RD_ARRAY_LEG 0xE8
00075 #define AT45DBX_CMDA_RD_ARRAY_LF_SM 0x03
00076 #define AT45DBX_CMDA_RD_ARRAY_AF_SM 0x0B
00077 #define AT45DBX_CMDA_RD_SECTOR_PROT_REG 0x32
00078 #define AT45DBX_CMDA_RD_SECTOR_LKDN_REG 0x35
00079 #define AT45DBX_CMDA_RD_SECURITY_REG 0x77
00080
00081
00082
00084
00085 #define AT45DBX_CMDB_ER_PAGE 0x81
00086 #define AT45DBX_CMDB_ER_BLOCK 0x50
00087 #define AT45DBX_CMDB_ER_SECTOR 0x7C
00088 #define AT45DBX_CMDB_ER_CHIP 0xC794809A
00089 #define AT45DBX_CMDB_XFR_PAGE_TO_BUF1 0x53
00090 #define AT45DBX_CMDB_XFR_PAGE_TO_BUF2 0x55
00091 #define AT45DBX_CMDB_CMP_PAGE_TO_BUF1 0x60
00092 #define AT45DBX_CMDB_CMP_PAGE_TO_BUF2 0x61
00093 #define AT45DBX_CMDB_PR_BUF1_TO_PAGE_ER 0x83
00094 #define AT45DBX_CMDB_PR_BUF2_TO_PAGE_ER 0x86
00095 #define AT45DBX_CMDB_PR_BUF1_TO_PAGE 0x88
00096 #define AT45DBX_CMDB_PR_BUF2_TO_PAGE 0x89
00097 #define AT45DBX_CMDB_PR_PAGE_TH_BUF1 0x82
00098 #define AT45DBX_CMDB_PR_PAGE_TH_BUF2 0x85
00099 #define AT45DBX_CMDB_RWR_PAGE_TH_BUF1 0x58
00100 #define AT45DBX_CMDB_RWR_PAGE_TH_BUF2 0x59
00101
00102
00103
00105
00106 #define AT45DBX_CMDC_RD_BUF1_LF_SM 0xD1
00107 #define AT45DBX_CMDC_RD_BUF2_LF_SM 0xD3
00108 #define AT45DBX_CMDC_RD_BUF1_AF_SM 0xD4
00109 #define AT45DBX_CMDC_RD_BUF2_AF_SM 0xD6
00110 #define AT45DBX_CMDC_RD_BUF1_AF_8M 0x54
00111 #define AT45DBX_CMDC_RD_BUF2_AF_8M 0x56
00112 #define AT45DBX_CMDC_WR_BUF1 0x84
00113 #define AT45DBX_CMDC_WR_BUF2 0x87
00114 #define AT45DBX_CMDC_RD_STATUS_REG 0xD7
00115 #define AT45DBX_CMDC_RD_MNFCT_DEV_ID_SM 0x9F
00116
00117
00118
00120
00121 #define AT45DBX_CMDD_EN_SECTOR_PROT 0x3D2A7FA9
00122 #define AT45DBX_CMDD_DIS_SECTOR_PROT 0x3D2A7F9A
00123 #define AT45DBX_CMDD_ER_SECTOR_PROT_REG 0x3D2A7FCF
00124 #define AT45DBX_CMDD_PR_SECTOR_PROT_REG 0x3D2A7FFC
00125 #define AT45DBX_CMDD_LKDN_SECTOR 0x3D2A7F30
00126 #define AT45DBX_CMDD_PR_SECURITY_REG 0x9B000000
00127 #define AT45DBX_CMDD_PR_CONF_REG 0x3D2A80A6
00128 #define AT45DBX_CMDD_DEEP_PWR_DN 0xB9
00129 #define AT45DBX_CMDD_RSM_DEEP_PWR_DN 0xAB
00130
00131
00132
00135
00136 #define AT45DBX_MSK_BUSY 0x80
00137 #define AT45DBX_BUSY 0x00
00138 #define AT45DBX_MSK_DENSITY 0x3C
00139
00140
00141 #if AT45DBX_MEM_SIZE == AT45DBX_2MB
00142
00145
00146 #define AT45DBX_DENSITY 0x2C
00147 #define AT45DBX_BYTE_ADDR_BITS 10
00148
00149
00150 #elif AT45DBX_MEM_SIZE == AT45DBX_4MB
00151
00154
00155 #define AT45DBX_DENSITY 0x34
00156 #define AT45DBX_BYTE_ADDR_BITS 10
00157
00158
00159 #elif AT45DBX_MEM_SIZE == AT45DBX_8MB
00160
00163
00164 #define AT45DBX_DENSITY 0x3C
00165 #define AT45DBX_BYTE_ADDR_BITS 11
00166
00167
00168 #else
00169 #error AT45DBX_MEM_SIZE is not defined to a supported value
00170 #endif
00171
00173 #define AT45DBX_PAGE_ADDR_BITS (AT45DBX_MEM_SIZE - AT45DBX_PAGE_BITS)
00174
00176 #define AT45DBX_PAGE_BITS (AT45DBX_BYTE_ADDR_BITS - 1)
00177
00179 #define AT45DBX_PAGE_SIZE (1 << AT45DBX_PAGE_BITS)
00180
00182 #define AT45DBX_MSK_PTR_BYTE ((1 << AT45DBX_PAGE_BITS) - 1)
00183
00185 #define AT45DBX_MSK_PTR_PAGE (((1 << AT45DBX_PAGE_ADDR_BITS) - 1) << AT45DBX_PAGE_BITS)
00186
00188 #define AT45DBX_MSK_PTR_SECTOR ((1 << AT45DBX_SECTOR_BITS) - 1)
00189
00190
00193 #define spi_write_dummy() spi_write(AT45DBX_SPI, 0xFF)
00194
00195
00197 static Bool at45dbx_busy;
00198
00200 static U32 gl_ptr_mem;
00201
00203 static U8 sector_buf[AT45DBX_SECTOR_SIZE];
00204
00205
00208
00209
00210
00211 Bool at45dbx_init(spi_options_t spiOptions, unsigned int pba_hz)
00212 {
00213
00214 for (spiOptions.reg = AT45DBX_SPI_FIRST_NPCS;
00215 spiOptions.reg < AT45DBX_SPI_FIRST_NPCS + AT45DBX_MEM_CNT;
00216 spiOptions.reg++)
00217 {
00218 if (spi_setupChipReg(AT45DBX_SPI, &spiOptions, pba_hz) != SPI_OK) return KO;
00219 }
00220
00221
00222 at45dbx_busy = FALSE;
00223
00224 return OK;
00225 }
00226
00227
00233 static void at45dbx_chipselect_df(U8 memidx, Bool bSelect)
00234 {
00235 if (bSelect)
00236 {
00237
00238 spi_selectChip(AT45DBX_SPI, AT45DBX_SPI_FIRST_NPCS + memidx);
00239 }
00240 else
00241 {
00242
00243 spi_unselectChip(AT45DBX_SPI, AT45DBX_SPI_FIRST_NPCS + memidx);
00244 }
00245 }
00246
00247
00248 Bool at45dbx_mem_check(void)
00249 {
00250 U8 df;
00251 U16 status = 0;
00252
00253
00254 for (df = 0; df < AT45DBX_MEM_CNT; df++)
00255 {
00256
00257 at45dbx_chipselect_df(df, TRUE);
00258
00259
00260 spi_write(AT45DBX_SPI, AT45DBX_CMDC_RD_STATUS_REG);
00261
00262
00263 spi_write_dummy();
00264 spi_read(AT45DBX_SPI, &status);
00265
00266
00267 at45dbx_chipselect_df(df, FALSE);
00268
00269
00270 if ((status & AT45DBX_MSK_DENSITY) < AT45DBX_DENSITY) return KO;
00271 }
00272
00273 return OK;
00274 }
00275
00276
00279 static void at45dbx_wait_ready(void)
00280 {
00281 U16 status;
00282
00283
00284 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
00285
00286
00287 spi_write(AT45DBX_SPI, AT45DBX_CMDC_RD_STATUS_REG);
00288
00289
00290 do
00291 {
00292
00293 spi_write_dummy();
00294 spi_read(AT45DBX_SPI, &status);
00295 } while ((status & AT45DBX_MSK_BUSY) == AT45DBX_BUSY);
00296
00297
00298 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00299 }
00300
00301
00302 Bool at45dbx_read_open(U32 sector)
00303 {
00304 U32 addr;
00305
00306
00307 gl_ptr_mem = sector << AT45DBX_SECTOR_BITS;
00308
00309
00310 if (at45dbx_busy) at45dbx_wait_ready();
00311 at45dbx_busy = FALSE;
00312
00313
00314 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
00315
00316
00317
00318
00319 spi_write(AT45DBX_SPI, AT45DBX_CMDA_RD_PAGE);
00320
00321
00322
00323
00324
00325
00326
00327 addr = (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS) |
00328 Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE);
00329 spi_write(AT45DBX_SPI, LSB2W(addr));
00330 spi_write(AT45DBX_SPI, LSB1W(addr));
00331 spi_write(AT45DBX_SPI, LSB0W(addr));
00332
00333
00334 spi_write_dummy();
00335 spi_write_dummy();
00336 spi_write_dummy();
00337 spi_write_dummy();
00338
00339 return OK;
00340 }
00341
00342
00343 void at45dbx_read_close(void)
00344 {
00345
00346 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00347
00348
00349 at45dbx_busy = FALSE;
00350 }
00351
00352
00353 Bool at45dbx_write_open(U32 sector)
00354 {
00355 U32 addr;
00356
00357
00358 gl_ptr_mem = sector << AT45DBX_SECTOR_BITS;
00359
00360
00361 if (at45dbx_busy) at45dbx_wait_ready();
00362 at45dbx_busy = FALSE;
00363
00364 #if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE
00365
00366 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
00367
00368
00369
00370
00371 spi_write(AT45DBX_SPI, AT45DBX_CMDB_XFR_PAGE_TO_BUF1);
00372
00373
00374
00375
00376
00377
00378
00379 addr = Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS;
00380 spi_write(AT45DBX_SPI, LSB2W(addr));
00381 spi_write(AT45DBX_SPI, LSB1W(addr));
00382 spi_write(AT45DBX_SPI, LSB0W(addr));
00383
00384
00385 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00386
00387
00388 at45dbx_wait_ready();
00389 #endif
00390
00391
00392 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, TRUE);
00393
00394
00395
00396
00397 spi_write(AT45DBX_SPI, AT45DBX_CMDB_PR_PAGE_TH_BUF1);
00398
00399
00400
00401
00402
00403
00404
00405 addr = (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_PAGE) << AT45DBX_BYTE_ADDR_BITS) |
00406 Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE);
00407 spi_write(AT45DBX_SPI, LSB2W(addr));
00408 spi_write(AT45DBX_SPI, LSB1W(addr));
00409 spi_write(AT45DBX_SPI, LSB0W(addr));
00410
00411 return OK;
00412 }
00413
00414
00415 void at45dbx_write_close(void)
00416 {
00417
00418 while (Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_SECTOR))
00419 {
00420 spi_write(AT45DBX_SPI, 0x00);
00421 gl_ptr_mem++;
00422 }
00423
00424
00425 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00426
00427
00428 at45dbx_busy = TRUE;
00429 }
00430
00431
00433
00434
00437
00438
00439
00440 U8 at45dbx_read_byte(void)
00441 {
00442 U16 data;
00443
00444
00445 if (at45dbx_busy)
00446 {
00447
00448
00449
00450
00451 at45dbx_busy = FALSE;
00452
00453
00454
00455 at45dbx_read_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS);
00456 }
00457
00458
00459 spi_write_dummy();
00460 spi_read(AT45DBX_SPI, &data);
00461 gl_ptr_mem++;
00462
00463
00464 if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
00465 {
00466
00467 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00468
00469
00470 at45dbx_busy = TRUE;
00471 }
00472
00473 return data;
00474 }
00475
00476
00477 Bool at45dbx_write_byte(U8 b)
00478 {
00479
00480 if (at45dbx_busy)
00481 {
00482
00483
00484
00485
00486
00487 at45dbx_write_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS);
00488 }
00489
00490
00491 spi_write(AT45DBX_SPI, b);
00492 gl_ptr_mem++;
00493
00494
00495 if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
00496 {
00497
00498 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00499
00500
00501 at45dbx_busy = TRUE;
00502 }
00503
00504 return OK;
00505 }
00506
00507
00509
00510
00513
00514
00515
00516 Bool at45dbx_read_multiple_sector(U16 nb_sector)
00517 {
00518 while (nb_sector--)
00519 {
00520
00521 at45dbx_read_sector_2_ram(sector_buf);
00522 at45dbx_read_multiple_sector_callback(sector_buf);
00523 }
00524
00525 return OK;
00526 }
00527
00528
00529 Bool at45dbx_write_multiple_sector(U16 nb_sector)
00530 {
00531 while (nb_sector--)
00532 {
00533
00534 at45dbx_write_multiple_sector_callback(sector_buf);
00535 at45dbx_write_sector_from_ram(sector_buf);
00536 }
00537
00538 return OK;
00539 }
00540
00541
00543
00544
00547
00548
00549
00550 Bool at45dbx_read_sector_2_ram(void *ram)
00551 {
00552 U8 *_ram = ram;
00553 U16 i;
00554 U16 data;
00555
00556
00557 if (at45dbx_busy)
00558 {
00559
00560
00561
00562
00563 at45dbx_busy = FALSE;
00564
00565
00566
00567 at45dbx_read_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS);
00568 }
00569
00570
00571 for (i = AT45DBX_SECTOR_SIZE; i; i--)
00572 {
00573
00574 spi_write_dummy();
00575 spi_read(AT45DBX_SPI, &data);
00576 *_ram++ = data;
00577 }
00578
00579
00580 gl_ptr_mem += AT45DBX_SECTOR_SIZE;
00581
00582 #if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE
00583
00584 if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
00585 #endif
00586 {
00587
00588 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00589
00590
00591 at45dbx_busy = TRUE;
00592 }
00593
00594 return OK;
00595 }
00596
00597
00598 Bool at45dbx_write_sector_from_ram(const void *ram)
00599 {
00600 const U8 *_ram = ram;
00601 U16 i;
00602
00603
00604 if (at45dbx_busy)
00605 {
00606
00607
00608
00609
00610
00611 at45dbx_write_open(gl_ptr_mem >> AT45DBX_SECTOR_BITS);
00612 }
00613
00614
00615 for (i = AT45DBX_SECTOR_SIZE; i; i--)
00616 {
00617
00618 spi_write(AT45DBX_SPI, *_ram++);
00619 }
00620
00621
00622 gl_ptr_mem += AT45DBX_SECTOR_SIZE;
00623
00624 #if AT45DBX_PAGE_SIZE > AT45DBX_SECTOR_SIZE
00625
00626 if (!Rd_bitfield(gl_ptr_mem, AT45DBX_MSK_PTR_BYTE))
00627 #endif
00628 {
00629
00630 at45dbx_chipselect_df(gl_ptr_mem >> AT45DBX_MEM_SIZE, FALSE);
00631
00632
00633 at45dbx_busy = TRUE;
00634 }
00635
00636 return OK;
00637 }
00638
00639
00641
00642
00643 #endif // AT45DBX_MEM == ENABLE