[AVR单片机] 关于AT45DB081的问题

[复制链接]
6015|15
 楼主| crystaling1984 发表于 2010-10-11 15:45 | 显示全部楼层 |阅读模式
我现在在改进一个设备,我们做的医疗器材,现在有台心血管功能仪,但是缺少存储数据及串口输出功能,现在我们需要加AT45DB081芯片来解决测试数据的存储、调用、删除等功能,我现在需要用C语言来完成这些功能,之前的设备的代码都有,使用KEIL51做的,现在哪位大哥能帮忙搞下这个存储及串口输出的C语言程序,以及这么加入到原来的程序中以实现整理功能。我是初学者,可是我们刚进公司,这个项目接手后我是头大了,我还在试用期,不想失去这份来之不易的工作,希望给位大侠能帮上忙,小弟感激不尽,可以加我qq45889779,也可以邮箱:crystaling1984@163.com
 楼主| crystaling1984 发表于 2010-10-12 08:45 | 显示全部楼层
没人解决啊!高手呢?出来帮帮小弟吧!
 楼主| crystaling1984 发表于 2010-10-12 08:46 | 显示全部楼层
没人解决啊!高手呢?出来帮帮小弟吧!
mxh0506 发表于 2010-10-12 13:12 | 显示全部楼层
可以参考这个贴子,有ATMEL的源程序
https://bbs.21ic.com/redirect.php ... 259&ptid=197540
 楼主| crystaling1984 发表于 2010-10-13 09:19 | 显示全部楼层
这个源程序出来后怎么样跟原来的设备程序融合呢?有没有高手再帮我下。我是菜鸟
 楼主| crystaling1984 发表于 2010-10-14 14:10 | 显示全部楼层
除了4楼真的没人可以帮帮忙啊,我需要详细点的。高手出来吧
john_light 发表于 2010-10-14 15:09 | 显示全部楼层

  1. /*
  2. * Copyright (C) 2006 by egnite Software GmbH. All rights reserved.
  3. * Copyright (C) 2008 by egnite GmbH. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. *    notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. *    notice, this list of conditions and the following disclaimer in the
  13. *    documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of
  15. *    contributors may be used to endorse or promote products derived
  16. *    from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  22. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  25. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  26. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  28. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * For additional information see http://www.ethernut.de/
  32. *
  33. */

  34. #include <cfg/os.h>
  35. #include <cfg/memory.h>

  36. #include <sys/timer.h>

  37. #include <string.h>
  38. #include <stdlib.h>

  39. #include <dev/at91_spi.h>
  40. #include <dev/at45db.h>

  41. #ifndef MAX_AT45_DEVICES
  42. #define MAX_AT45_DEVICES        1
  43. #endif

  44. #ifndef MAX_AT45_CMDLEN
  45. #define MAX_AT45_CMDLEN         8
  46. #endif

  47. #ifndef AT45_CONF_DFSPI
  48. #define AT45_CONF_DFSPI         SPI0_BASE
  49. #endif

  50. #ifndef AT45_CONF_DFPCS
  51. #define AT45_CONF_DFPCS         1
  52. #endif

  53. #ifndef AT45_ERASE_WAIT
  54. #define AT45_ERASE_WAIT         3000
  55. #endif

  56. #ifndef AT45_CHIP_ERASE_WAIT
  57. #define AT45_CHIP_ERASE_WAIT    50000
  58. #endif

  59. #ifndef AT45_WRITE_POLLS
  60. #define AT45_WRITE_POLLS        1000
  61. #endif

  62. #define DFCMD_CONT_READ_LF      0x03

  63. #define DFCMD_CONT_READ_HF      0x0B

  64. #define DFCMD_BLOCK_ERASE       0x50

  65. #define DFCMD_SECTOR_ERASE      0x7C

  66. #define DFCMD_PAGE_ERASE        0x81

  67. #define DFCMD_BUF1_PROG         0x82

  68. #define DFCMD_BUF1_FLASH        0x83

  69. #define DFCMD_BUF1_WRITE        0x84

  70. #define DFCMD_BUF2_PROG         0x85

  71. #define DFCMD_BUF2_FLASH        0x86

  72. #define DFCMD_BUF2_WRITE        0x87

  73. #define DFCMD_BUF1_FLASH_NE     0x88

  74. #define DFCMD_BUF2_FLASH_NE     0x89

  75. #define DFCMD_CHIP_ERASE        0xC7

  76. #define DFCMD_BUF1_READ_LF      0xD1

  77. #define DFCMD_READ_PAGE         0xD2

  78. #define DFCMD_BUF2_READ_LF      0xD3

  79. #define DFCMD_BUF1_READ         0xD4

  80. #define DFCMD_BUF2_READ         0xD6

  81. #define DFCMD_READ_STATUS       0xD7

  82. #define DFCMD_CONT_READ         0xE8

  83. #define AT45DB_AT91


  84. #if defined(AT45DB_SPI0_DEVICE)

  85. #include <dev/sppif0.h>
  86. #if defined(AT45DB_RESET_ACTIVE_HIGH)
  87. #define SpiReset(act)       Sppi0ChipReset(AT45DB_SPI0_DEVICE, act)
  88. #else
  89. #define SpiReset(act)       Sppi0ChipReset(AT45DB_SPI0_DEVICE, !act)
  90. #endif
  91. #define SpiSetMode()        Sppi0SetMode(AT45DB_SPI0_DEVICE, AT45DB_SPI_MODE)
  92. #define SpiSetSpeed()       Sppi0SetSpeed(AT45DB_SPI0_DEVICE, AT45DB_SPI_RATE)
  93. #if defined(AT45DB_SELECT_ACTIVE_HIGH)
  94. #define SpiSelect()         Sppi0SelectDevice(AT45DB_SPI0_DEVICE)
  95. #define SpiDeselect()       Sppi0DeselectDevice(AT45DB_SPI0_DEVICE)
  96. #else
  97. #define SpiSelect()         Sppi0NegSelectDevice(AT45DB_SPI0_DEVICE)
  98. #define SpiDeselect()       Sppi0NegDeselectDevice(AT45DB_SPI0_DEVICE)
  99. #endif
  100. #define SpiByte             Sppi0Byte

  101. #elif defined(AT45DB_SBBI0_DEVICE)

  102. #include <dev/sbbif0.h>
  103. #if defined(AT45DB_RESET_ACTIVE_HIGH)
  104. #define SpiReset(act)       Sbbi0ChipReset(AT45DB_SBBI0_DEVICE, act)
  105. #else
  106. #define SpiReset(act)       Sbbi0ChipReset(AT45DB_SBBI0_DEVICE, !act)
  107. #endif
  108. #define SpiSetMode()        Sbbi0SetMode(AT45DB_SBBI0_DEVICE, AT45DB_SPI_MODE)
  109. #define SpiSetSpeed()       Sbbi0SetSpeed(AT45DB_SBBI0_DEVICE, AT45DB_SPI_RATE)
  110. #if defined(AT45DB_SELECT_ACTIVE_HIGH)
  111. #define SpiSelect()         Sbbi0SelectDevice(AT45DB_SBBI0_DEVICE)
  112. #define SpiDeselect()       Sbbi0DeselectDevice(AT45DB_SBBI0_DEVICE)
  113. #else
  114. #define SpiSelect()         Sbbi0NegSelectDevice(AT45DB_SBBI0_DEVICE)
  115. #define SpiDeselect()       Sbbi0NegDeselectDevice(AT45DB_SBBI0_DEVICE)
  116. #endif
  117. #define SpiByte             Sbbi0Byte

  118. #endif

  119. typedef struct _AT45_DEVTAB {
  120.     uint32_t devt_pages;
  121.     unsigned int devt_pagsiz;
  122.     unsigned int devt_offs;
  123.     uint8_t devt_srmsk;
  124.     uint8_t devt_srval;
  125. } AT45_DEVTAB;

  126. typedef struct _AT45DB_DCB {
  127.     AT45_DEVTAB *dcb_devt;
  128.     unsigned int dcb_spibas;
  129.     unsigned int dcb_spipcs;
  130.     uint8_t dcb_cmdbuf[MAX_AT45_CMDLEN];
  131. } AT45DB_DCB;

  132. AT45_DEVTAB at45_devt[] = {
  133.     {512, 264, 9, 0x3C, 0x0C},  /* AT45DB011B - 128kB */
  134.     {1025, 264, 9, 0x3C, 0x14}, /* AT45DB021B - 256kB */
  135.     {2048, 264, 9, 0x3C, 0x1C}, /* AT45DB041B - 512kB */
  136.     {4096, 264, 9, 0x3C, 0x24}, /* AT45DB081B - 1MB */
  137.     {4096, 528, 10, 0x3C, 0x2C},        /* AT45DB0161B - 2MB */
  138.     {8192, 528, 10, 0x3C, 0x34},        /* AT45DB0321B - 4MB */
  139.     {8192, 1056, 11, 0x38, 0x38},       /* AT45DB0642 - 8MB */
  140.     {0, 0, 0, 0, 0}             /* End of table */
  141. };

  142. static AT45DB_DCB dcbtab[MAX_AT45_DEVICES];

  143. /* Number of active chips. */
  144. static uint_least8_t dcbnum;

  145. /* Chip used for parameter storage. */
  146. static int dd_param = -1;

  147. int At45dbSendCmd(int dd, uint8_t op, uint32_t parm, int len, CONST void *tdata, void *rdata, int datalen)
  148. {
  149.     uint8_t *cb = dcbtab[dd].dcb_cmdbuf;

  150.     if (len > MAX_AT45_CMDLEN) {
  151.         return -1;
  152.     }
  153.     memset(cb, 0, len);
  154.     cb[0] = op;
  155.     if (parm) {
  156.         cb[1] = (uint8_t) (parm >> 16);
  157.         cb[2] = (uint8_t) (parm >> 8);
  158.         cb[3] = (uint8_t) parm;
  159.     }
  160.     return At91SpiTransfer2(dcbtab[dd].dcb_spibas, dcbtab[dd].dcb_spipcs, cb, cb, len, tdata, rdata, datalen);
  161. }

  162. uint8_t At45dbGetStatus(int dd)
  163. {
  164.     uint8_t buf[2] = { DFCMD_READ_STATUS, 0xFF };

  165.     if (At91SpiTransfer2(dcbtab[dd].dcb_spibas, dcbtab[dd].dcb_spipcs, buf, buf, 2, NULL, NULL, 0)) {
  166.         return (uint8_t) - 1;
  167.     }
  168.     return buf[1];
  169. }

  170. int At45dbWaitReady(int dd, uint32_t tmo, int poll)
  171. {
  172.     uint8_t sr;

  173.     while (((sr = At45dbGetStatus(dd)) & 0x80) == 0) {
  174.         if (!poll) {
  175.             NutSleep(1);
  176.         }
  177.         if (tmo-- == 0) {
  178.             return -1;
  179.         }
  180.     }
  181.     return 0;
  182. }

  183. int At45dbInit(unsigned int spibas, unsigned int spipcs)
  184. {
  185.     int dd = -1;
  186.     uint8_t sr;
  187.     uint_fast8_t i;

  188.     for (i = 0; i < dcbnum; i++) {
  189.         if (dcbtab[i].dcb_spibas == spibas && dcbtab[i].dcb_spipcs == spipcs) {
  190.             return i;
  191.         }
  192.     }

  193.     if (dcbnum >= MAX_AT45_DEVICES) {
  194.         return -1;
  195.     }

  196. #if defined(MCU_AT91SAM7X) || defined(MCU_AT91SAM7SE) || defined(MCU_AT91SAM9260) || defined(MCU_AT91SAM9XE)
  197.     At91SpiInit(spibas);
  198.     At91SpiReset(spibas);
  199.     At91SpiInitChipSelects(spibas, _BV(spipcs));
  200.     At91SpiSetRate(spibas, spipcs, 1000000);
  201.     At91SpiSetModeFlags(spibas, spipcs, SPIMF_MASTER | SPIMF_SCKIAHI | SPIMF_CAPRISE);
  202. #elif defined(MCU_AT91R40008)
  203. #endif

  204.     dcbtab[dcbnum].dcb_spibas = spibas;
  205.     dcbtab[dcbnum].dcb_spipcs = spipcs;
  206.     sr = At45dbGetStatus(dcbnum);

  207.     for (i = 0; at45_devt[i].devt_pages; i++) {
  208.         if ((sr & at45_devt[i].devt_srmsk) == at45_devt[i].devt_srval) {
  209.             dcbtab[dcbnum].dcb_devt = &at45_devt[i];
  210.             dd = dcbnum++;
  211.             break;
  212.         }
  213.     }
  214.     return dd;
  215. }

  216. int At45dbPageErase(int dd, uint32_t pgn)
  217. {
  218.     pgn <<= dcbtab[dd].dcb_devt->devt_offs;
  219.     return At45dbSendCmd(dd, DFCMD_PAGE_ERASE, pgn, 4, NULL, NULL, 0);
  220. }

  221. int At45dbChipErase(void)
  222. {
  223.     return -1;
  224. }

  225. int At45dbPageRead(int dd, uint32_t pgn, void *data, unsigned int len)
  226. {
  227.     pgn <<= dcbtab[dd].dcb_devt->devt_offs;
  228.     return At45dbSendCmd(dd, DFCMD_CONT_READ, pgn, 8, data, data, len);
  229. }

  230. int At45dbPageWrite(int dd, uint32_t pgn, CONST void *data, unsigned int len)
  231. {
  232.     int rc = -1;
  233.     void *rp;

  234.     if ((rp = malloc(len)) != NULL) {
  235.         /* Copy data to dataflash RAM buffer. */
  236.         if (At45dbSendCmd(dd, DFCMD_BUF1_WRITE, 0, 4, data, rp, len) == 0) {
  237.             /* Flash RAM buffer. */
  238.             pgn <<= dcbtab[dd].dcb_devt->devt_offs;
  239.             if (At45dbSendCmd(dd, DFCMD_BUF1_FLASH, pgn, 4, NULL, NULL, 0) == 0) {
  240.                 rc = At45dbWaitReady(dd, AT45_WRITE_POLLS, 1);
  241.             }
  242.         }
  243.         free(rp);
  244.     }
  245.     return rc;
  246. }

  247. uint32_t At45dbPages(int dd)
  248. {
  249.     return dcbtab[dd].dcb_devt->devt_pages;
  250. }

  251. unsigned int At45dbPageSize(int dd)
  252. {
  253.     return dcbtab[dd].dcb_devt->devt_pagsiz;
  254. }

  255. uint32_t At45dbParamPage(void)
  256. {
  257. #ifdef AT45_CONF_PAGE
  258.     return AT45_CONF_PAGE;
  259. #else
  260.     return dcbtab[dd_param].dcb_devt->devt_pages - 1;
  261. #endif
  262. }

  263. int At45dbParamSize(void)
  264. {
  265.     int rc;

  266.     if (dd_param == -1 && (dd_param = At45dbInit(AT45_CONF_DFSPI, AT45_CONF_DFPCS)) == -1) {
  267.         return -1;
  268.     }
  269. #ifdef AT45_CONF_SIZE
  270.     rc = AT45_CONF_SIZE;
  271. #else
  272.     rc = dcbtab[dd_param].dcb_devt->devt_pagsiz;
  273. #endif
  274.     return rc;
  275. }

  276. int At45dbParamRead(unsigned int pos, void *data, unsigned int len)
  277. {
  278.     int rc = -1;
  279.     uint8_t *buff;
  280.     int csize = At45dbParamSize();
  281.     uint32_t cpage = At45dbParamPage();

  282.     /* Load the complete configuration area. */
  283.     if (csize > len && (buff = malloc(csize)) != NULL) {
  284.         rc = At45dbPageRead(dd_param, cpage, buff, csize);
  285.         /* Copy requested contents to caller's buffer. */
  286.         memcpy(data, buff + pos, len);
  287.         free(buff);
  288.     }
  289.     return rc;
  290. }

  291. int At45dbParamWrite(unsigned int pos, CONST void *data, unsigned int len)
  292. {
  293.     int rc = -1;
  294.     uint8_t *buff;
  295.     int csize = At45dbParamSize();
  296.     uint32_t cpage = At45dbParamPage();

  297.     /* Load the complete configuration area. */
  298.     if (csize > len && (buff = malloc(csize)) != NULL) {
  299.         rc = At45dbPageRead(dd_param, cpage, buff, csize);
  300.         /* Compare old with new contents. */
  301.         if (memcmp(buff + pos, data, len)) {
  302.             /* New contents differs. Copy it into the sector buffer. */
  303.             memcpy(buff + pos, data, len);
  304.             /* Erase sector and write new data. */
  305.             rc = At45dbPageWrite(dd_param, cpage, buff, csize);
  306.         }
  307.         free(buff);
  308.     }
  309.     return rc;
  310. }


出处在此:Nut/OS API
john_light 发表于 2010-10-14 15:22 | 显示全部楼层

  1. /*
  2. * Atmel SPI DataFlash support
  3. *
  4. * Copyright (C) 2008 Atmel Corporation
  5. * Licensed under the GPL-2 or later.
  6. */

  7. #include <common.h>
  8. #include <malloc.h>
  9. #include <spi_flash.h>

  10. #include "spi_flash_internal.h"

  11. /* AT45-specific commands */
  12. #define CMD_AT45_READ_STATUS                0xd7
  13. #define CMD_AT45_ERASE_PAGE                0x81
  14. #define CMD_AT45_LOAD_PROG_BUF1                0x82
  15. #define CMD_AT45_LOAD_BUF1                0x84
  16. #define CMD_AT45_LOAD_PROG_BUF2                0x85
  17. #define CMD_AT45_LOAD_BUF2                0x87
  18. #define CMD_AT45_PROG_BUF1                0x88
  19. #define CMD_AT45_PROG_BUF2                0x89

  20. /* AT45 status register bits */
  21. #define AT45_STATUS_P2_PAGE_SIZE        (1 << 0)
  22. #define AT45_STATUS_READY                (1 << 7)

  23. /* DataFlash family IDs, as obtained from the second idcode byte */
  24. #define DF_FAMILY_AT26F                        0
  25. #define DF_FAMILY_AT45                        1
  26. #define DF_FAMILY_AT26DF                2        /* AT25DF and AT26DF */

  27. struct atmel_spi_flash_params {
  28.         u8                idcode1;
  29.         /* Log2 of page size in power-of-two mode */
  30.         u8                l2_page_size;
  31.         u8                pages_per_block;
  32.         u8                blocks_per_sector;
  33.         u8                nr_sectors;
  34.         const char        *name;
  35. };

  36. /* spi_flash needs to be first so upper layers can free() it */
  37. struct atmel_spi_flash {
  38.         struct spi_flash flash;
  39.         const struct atmel_spi_flash_params *params;
  40. };

  41. static inline struct atmel_spi_flash *
  42. to_atmel_spi_flash(struct spi_flash *flash)
  43. {
  44.         return container_of(flash, struct atmel_spi_flash, flash);
  45. }

  46. static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
  47.         {
  48.                 .idcode1                = 0x22,
  49.                 .l2_page_size                = 8,
  50.                 .pages_per_block        = 8,
  51.                 .blocks_per_sector        = 16,
  52.                 .nr_sectors                = 4,
  53.                 .name                        = "AT45DB011D",
  54.         },
  55.         {
  56.                 .idcode1                = 0x23,
  57.                 .l2_page_size                = 8,
  58.                 .pages_per_block        = 8,
  59.                 .blocks_per_sector        = 16,
  60.                 .nr_sectors                = 8,
  61.                 .name                        = "AT45DB021D",
  62.         },
  63.         {
  64.                 .idcode1                = 0x24,
  65.                 .l2_page_size                = 8,
  66.                 .pages_per_block        = 8,
  67.                 .blocks_per_sector        = 32,
  68.                 .nr_sectors                = 8,
  69.                 .name                        = "AT45DB041D",
  70.         },
  71.         {
  72.                 .idcode1                = 0x25,
  73.                 .l2_page_size                = 8,
  74.                 .pages_per_block        = 8,
  75.                 .blocks_per_sector        = 32,
  76.                 .nr_sectors                = 16,
  77.                 .name                        = "AT45DB081D",
  78.         },
  79.         {
  80.                 .idcode1                = 0x26,
  81.                 .l2_page_size                = 9,
  82.                 .pages_per_block        = 8,
  83.                 .blocks_per_sector        = 32,
  84.                 .nr_sectors                = 16,
  85.                 .name                        = "AT45DB161D",
  86.         },
  87.         {
  88.                 .idcode1                = 0x27,
  89.                 .l2_page_size                = 9,
  90.                 .pages_per_block        = 8,
  91.                 .blocks_per_sector        = 64,
  92.                 .nr_sectors                = 64,
  93.                 .name                        = "AT45DB321D",
  94.         },
  95.         {
  96.                 .idcode1                = 0x28,
  97.                 .l2_page_size                = 10,
  98.                 .pages_per_block        = 8,
  99.                 .blocks_per_sector        = 32,
  100.                 .nr_sectors                = 32,
  101.                 .name                        = "AT45DB642D",
  102.         },
  103. };

  104. static int at45_wait_ready(struct spi_flash *flash, unsigned long timeout)
  105. {
  106.         struct spi_slave *spi = flash->spi;
  107.         unsigned long timebase;
  108.         int ret;
  109.         u8 cmd = CMD_AT45_READ_STATUS;
  110.         u8 status;

  111.         timebase = get_timer(0);

  112.         ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
  113.         if (ret)
  114.                 return -1;

  115.         do {
  116.                 ret = spi_xfer(spi, 8, NULL, &status, 0);
  117.                 if (ret)
  118.                         return -1;

  119.                 if (status & AT45_STATUS_READY)
  120.                         break;
  121.         } while (get_timer(timebase) < timeout);

  122.         /* Deactivate CS */
  123.         spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);

  124.         if (status & AT45_STATUS_READY)
  125.                 return 0;

  126.         /* Timed out */
  127.         return -1;
  128. }

  129. /*
  130. * Assemble the address part of a command for AT45 devices in
  131. * non-power-of-two page size mode.
  132. */
  133. static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
  134. {
  135.         unsigned long page_addr;
  136.         unsigned long byte_addr;
  137.         unsigned long page_size;
  138.         unsigned int page_shift;

  139.         /*
  140.          * The "extra" space per page is the power-of-two page size
  141.          * divided by 32.
  142.          */
  143.         page_shift = asf->params->l2_page_size;
  144.         page_size = (1 << page_shift) + (1 << (page_shift - 5));
  145.         page_shift++;
  146.         page_addr = offset / page_size;
  147.         byte_addr = offset % page_size;

  148.         cmd[0] = page_addr >> (16 - page_shift);
  149.         cmd[1] = page_addr << (page_shift - 8) | (byte_addr >> 8);
  150.         cmd[2] = byte_addr;
  151. }

  152. static int dataflash_read_fast_p2(struct spi_flash *flash,
  153.                 u32 offset, size_t len, void *buf)
  154. {
  155.         u8 cmd[5];

  156.         cmd[0] = CMD_READ_ARRAY_FAST;
  157.         cmd[1] = offset >> 16;
  158.         cmd[2] = offset >> 8;
  159.         cmd[3] = offset;
  160.         cmd[4] = 0x00;

  161.         return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
  162. }

  163. static int dataflash_read_fast_at45(struct spi_flash *flash,
  164.                 u32 offset, size_t len, void *buf)
  165. {
  166.         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
  167.         u8 cmd[5];

  168.         cmd[0] = CMD_READ_ARRAY_FAST;
  169.         at45_build_address(asf, cmd + 1, offset);
  170.         cmd[4] = 0x00;

  171.         return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
  172. }

  173. /*
  174. * TODO: the two write funcs (_p2/_at45) should get unified ...
  175. */
  176. static int dataflash_write_p2(struct spi_flash *flash,
  177.                 u32 offset, size_t len, const void *buf)
  178. {
  179.         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
  180.         unsigned long page_size;
  181.         u32 addr = offset;
  182.         size_t chunk_len;
  183.         size_t actual;
  184.         int ret;
  185.         u8 cmd[4];

  186.         /*
  187.          * TODO: This function currently uses only page buffer #1.  We can
  188.          * speed this up by using both buffers and loading one buffer while
  189.          * the other is being programmed into main memory.
  190.          */

  191.         page_size = (1 << asf->params->l2_page_size);

  192.         ret = spi_claim_bus(flash->spi);
  193.         if (ret) {
  194.                 debug("SF: Unable to claim SPI bus\n");
  195.                 return ret;
  196.         }

  197.         for (actual = 0; actual < len; actual += chunk_len) {
  198.                 chunk_len = min(len - actual, page_size - (addr % page_size));

  199.                 /* Use the same address bits for both commands */
  200.                 cmd[0] = CMD_AT45_LOAD_BUF1;
  201.                 cmd[1] = addr >> 16;
  202.                 cmd[2] = addr >> 8;
  203.                 cmd[3] = addr;

  204.                 ret = spi_flash_cmd_write(flash->spi, cmd, 4,
  205.                                 buf + actual, chunk_len);
  206.                 if (ret < 0) {
  207.                         debug("SF: Loading AT45 buffer failed\n");
  208.                         goto out;
  209.                 }

  210.                 cmd[0] = CMD_AT45_PROG_BUF1;
  211.                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
  212.                 if (ret < 0) {
  213.                         debug("SF: AT45 page programming failed\n");
  214.                         goto out;
  215.                 }

  216.                 ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
  217.                 if (ret < 0) {
  218.                         debug("SF: AT45 page programming timed out\n");
  219.                         goto out;
  220.                 }

  221.                 addr += chunk_len;
  222.         }

  223.         debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
  224.                         len, offset);
  225.         ret = 0;

  226. out:
  227.         spi_release_bus(flash->spi);
  228.         return ret;
  229. }

  230. static int dataflash_write_at45(struct spi_flash *flash,
  231.                 u32 offset, size_t len, const void *buf)
  232. {
  233.         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
  234.         unsigned long page_addr;
  235.         unsigned long byte_addr;
  236.         unsigned long page_size;
  237.         unsigned int page_shift;
  238.         size_t chunk_len;
  239.         size_t actual;
  240.         int ret;
  241.         u8 cmd[4];

  242.         /*
  243.          * TODO: This function currently uses only page buffer #1.  We can
  244.          * speed this up by using both buffers and loading one buffer while
  245.          * the other is being programmed into main memory.
  246.          */

  247.         page_shift = asf->params->l2_page_size;
  248.         page_size = (1 << page_shift) + (1 << (page_shift - 5));
  249.         page_shift++;
  250.         page_addr = offset / page_size;
  251.         byte_addr = offset % page_size;

  252.         ret = spi_claim_bus(flash->spi);
  253.         if (ret) {
  254.                 debug("SF: Unable to claim SPI bus\n");
  255.                 return ret;
  256.         }

  257.         for (actual = 0; actual < len; actual += chunk_len) {
  258.                 chunk_len = min(len - actual, page_size - byte_addr);

  259.                 /* Use the same address bits for both commands */
  260.                 cmd[0] = CMD_AT45_LOAD_BUF1;
  261.                 cmd[1] = page_addr >> (16 - page_shift);
  262.                 cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
  263.                 cmd[3] = byte_addr;

  264.                 ret = spi_flash_cmd_write(flash->spi, cmd, 4,
  265.                                 buf + actual, chunk_len);
  266.                 if (ret < 0) {
  267.                         debug("SF: Loading AT45 buffer failed\n");
  268.                         goto out;
  269.                 }

  270.                 cmd[0] = CMD_AT45_PROG_BUF1;
  271.                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
  272.                 if (ret < 0) {
  273.                         debug("SF: AT45 page programming failed\n");
  274.                         goto out;
  275.                 }

  276.                 ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
  277.                 if (ret < 0) {
  278.                         debug("SF: AT45 page programming timed out\n");
  279.                         goto out;
  280.                 }

  281.                 page_addr++;
  282.                 byte_addr = 0;
  283.         }

  284.         debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
  285.                         len, offset);
  286.         ret = 0;

  287. out:
  288.         spi_release_bus(flash->spi);
  289.         return ret;
  290. }

  291. /*
  292. * TODO: the two erase funcs (_p2/_at45) should get unified ...
  293. */
  294. int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
  295. {
  296.         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
  297.         unsigned long page_size;

  298.         size_t actual;
  299.         int ret;
  300.         u8 cmd[4];

  301.         /*
  302.          * TODO: This function currently uses page erase only. We can
  303.          * probably speed things up by using block and/or sector erase
  304.          * when possible.
  305.          */

  306.         page_size = (1 << asf->params->l2_page_size);

  307.         if (offset % page_size || len % page_size) {
  308.                 debug("SF: Erase offset/length not multiple of page size\n");
  309.                 return -1;
  310.         }

  311.         cmd[0] = CMD_AT45_ERASE_PAGE;
  312.         cmd[3] = 0x00;

  313.         ret = spi_claim_bus(flash->spi);
  314.         if (ret) {
  315.                 debug("SF: Unable to claim SPI bus\n");
  316.                 return ret;
  317.         }

  318.         for (actual = 0; actual < len; actual += page_size) {
  319.                 cmd[1] = offset >> 16;
  320.                 cmd[2] = offset >> 8;

  321.                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
  322.                 if (ret < 0) {
  323.                         debug("SF: AT45 page erase failed\n");
  324.                         goto out;
  325.                 }

  326.                 ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
  327.                 if (ret < 0) {
  328.                         debug("SF: AT45 page erase timed out\n");
  329.                         goto out;
  330.                 }

  331.                 offset += page_size;
  332.         }

  333.         debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
  334.                         len, offset);
  335.         ret = 0;

  336. out:
  337.         spi_release_bus(flash->spi);
  338.         return ret;
  339. }

  340. int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
  341. {
  342.         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
  343.         unsigned long page_addr;
  344.         unsigned long page_size;
  345.         unsigned int page_shift;
  346.         size_t actual;
  347.         int ret;
  348.         u8 cmd[4];

  349.         /*
  350.          * TODO: This function currently uses page erase only. We can
  351.          * probably speed things up by using block and/or sector erase
  352.          * when possible.
  353.          */

  354.         page_shift = asf->params->l2_page_size;
  355.         page_size = (1 << page_shift) + (1 << (page_shift - 5));
  356.         page_shift++;
  357.         page_addr = offset / page_size;

  358.         if (offset % page_size || len % page_size) {
  359.                 debug("SF: Erase offset/length not multiple of page size\n");
  360.                 return -1;
  361.         }

  362.         cmd[0] = CMD_AT45_ERASE_PAGE;
  363.         cmd[3] = 0x00;

  364.         ret = spi_claim_bus(flash->spi);
  365.         if (ret) {
  366.                 debug("SF: Unable to claim SPI bus\n");
  367.                 return ret;
  368.         }

  369.         for (actual = 0; actual < len; actual += page_size) {
  370.                 cmd[1] = page_addr >> (16 - page_shift);
  371.                 cmd[2] = page_addr << (page_shift - 8);

  372.                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
  373.                 if (ret < 0) {
  374.                         debug("SF: AT45 page erase failed\n");
  375.                         goto out;
  376.                 }

  377.                 ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
  378.                 if (ret < 0) {
  379.                         debug("SF: AT45 page erase timed out\n");
  380.                         goto out;
  381.                 }

  382.                 page_addr++;
  383.         }

  384.         debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
  385.                         len, offset);
  386.         ret = 0;

  387. out:
  388.         spi_release_bus(flash->spi);
  389.         return ret;
  390. }

  391. struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
  392. {
  393.         const struct atmel_spi_flash_params *params;
  394.         unsigned page_size;
  395.         unsigned int family;
  396.         struct atmel_spi_flash *asf;
  397.         unsigned int i;
  398.         int ret;
  399.         u8 status;

  400.         for (i = 0; i < ARRAY_SIZE(atmel_spi_flash_table); i++) {
  401.                 params = &atmel_spi_flash_table[i];
  402.                 if (params->idcode1 == idcode[1])
  403.                         break;
  404.         }

  405.         if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
  406.                 debug("SF: Unsupported DataFlash ID %02x\n",
  407.                                 idcode[1]);
  408.                 return NULL;
  409.         }

  410.         asf = malloc(sizeof(struct atmel_spi_flash));
  411.         if (!asf) {
  412.                 debug("SF: Failed to allocate memory\n");
  413.                 return NULL;
  414.         }

  415.         asf->params = params;
  416.         asf->flash.spi = spi;
  417.         asf->flash.name = params->name;

  418.         /* Assuming power-of-two page size initially. */
  419.         page_size = 1 << params->l2_page_size;

  420.         family = idcode[1] >> 5;

  421.         switch (family) {
  422.         case DF_FAMILY_AT45:
  423.                 /*
  424.                  * AT45 chips have configurable page size. The status
  425.                  * register indicates which configuration is active.
  426.                  */
  427.                 ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
  428.                 if (ret)
  429.                         goto err;

  430.                 debug("SF: AT45 status register: %02x\n", status);

  431.                 if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
  432.                         asf->flash.read = dataflash_read_fast_at45;
  433.                         asf->flash.write = dataflash_write_at45;
  434.                         asf->flash.erase = dataflash_erase_at45;
  435.                         page_size += 1 << (params->l2_page_size - 5);
  436.                 } else {
  437.                         asf->flash.read = dataflash_read_fast_p2;
  438.                         asf->flash.write = dataflash_write_p2;
  439.                         asf->flash.erase = dataflash_erase_p2;
  440.                 }

  441.                 break;

  442.         case DF_FAMILY_AT26F:
  443.         case DF_FAMILY_AT26DF:
  444.                 asf->flash.read = dataflash_read_fast_p2;
  445.                 break;

  446.         default:
  447.                 debug("SF: Unsupported DataFlash family %u\n", family);
  448.                 goto err;
  449.         }

  450.         asf->flash.size = page_size * params->pages_per_block
  451.                                 * params->blocks_per_sector
  452.                                 * params->nr_sectors;

  453.         printf("SF: Detected %s with page size %u, total ",
  454.                params->name, page_size);
  455.         print_size(asf->flash.size, "\n");

  456.         return &asf->flash;

  457. err:
  458.         free(asf);
  459.         return NULL;
  460. }
出处:U-Boot
能不能参透就看你的造化了。

评分

参与人数 1威望 +1 收起 理由
crystaling1984 + 1

查看全部评分

粉丝 发表于 2010-10-14 18:37 | 显示全部楼层
楼上的贴子有意思。
john_light 发表于 2010-10-15 12:25 | 显示全部楼层
烦请9楼不吝赐教
 楼主| crystaling1984 发表于 2010-10-18 09:11 | 显示全部楼层
8# john_light

高手:你给我回的那个程序第一个是AT45DB的c源程序吗?8楼还留了个程序是什么的呢?
 楼主| crystaling1984 发表于 2010-10-18 09:11 | 显示全部楼层
8# john_light

高手:你给我回的那个程序第一个是AT45DB的c源程序吗?8楼还留了个程序是什么的呢?
 楼主| crystaling1984 发表于 2010-10-18 09:11 | 显示全部楼层
8# john_light

高手:你给我回的那个程序第一个是AT45DB的c源程序吗?8楼还留了个程序是什么的呢?
john_light 发表于 2010-10-18 11:47 | 显示全部楼层
两个源程序都是AT45系列Flash的驱动源码,由不同的人写就。

你需要自己消化,挑出自己能用的部分。
 楼主| crystaling1984 发表于 2010-10-19 08:32 | 显示全部楼层
14# john_light

能不能帮忙下把我需要的挑下给我,我是这方面的新手,消化需要时间,但是公司的任务是限时间的,求你帮忙下了
john_light 发表于 2010-10-19 08:34 | 显示全部楼层
这点,帮不了你。

另找高人吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

41

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部