xref: /nrf52832-nimble/rt-thread/components/drivers/spi/spi_flash_at45dbxx.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  *
4*10465441SEvalZero  * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero  *
6*10465441SEvalZero  * Change Logs:
7*10465441SEvalZero  * Date           Author       Notes
8*10465441SEvalZero  * 2011-12-16     aozima       the first version
9*10465441SEvalZero  */
10*10465441SEvalZero 
11*10465441SEvalZero #include <stdint.h>
12*10465441SEvalZero #include "spi_flash_at45dbxx.h"
13*10465441SEvalZero 
14*10465441SEvalZero #define FLASH_DEBUG
15*10465441SEvalZero #define DMA_BUFFER_SIZE                         512
16*10465441SEvalZero 
17*10465441SEvalZero #ifdef FLASH_DEBUG
18*10465441SEvalZero #define FLASH_TRACE         rt_kprintf
19*10465441SEvalZero #else
20*10465441SEvalZero #define FLASH_TRACE(...)
21*10465441SEvalZero #endif /**< #ifdef FLASH_DEBUG */
22*10465441SEvalZero 
23*10465441SEvalZero /* JEDEC Manufacturer’s ID */
24*10465441SEvalZero #define MF_ID                (0x1F) /* atmel */
25*10465441SEvalZero #define DENSITY_CODE_011D    (0x02) /* AT45DB011D Density Code : 00010 = 1-Mbit */
26*10465441SEvalZero #define DENSITY_CODE_021D    (0x03) /* AT45DB021D Density Code : 00011 = 2-Mbit */
27*10465441SEvalZero #define DENSITY_CODE_041D    (0x04) /* AT45DB041D Density Code : 00100 = 4-Mbit */
28*10465441SEvalZero #define DENSITY_CODE_081D    (0x05) /* AT45DB081D Density Code : 00101 = 8-Mbit */
29*10465441SEvalZero #define DENSITY_CODE_161D    (0x06) /* AT45DB161D Density Code : 00110 = 16-Mbit */
30*10465441SEvalZero #define DENSITY_CODE_321D    (0x07) /* AT45DB321D Density Code : 00111 = 32-Mbit */
31*10465441SEvalZero #define DENSITY_CODE_642D    (0x08) /* AT45DB642D Density Code : 01000 = 64-Mbit */
32*10465441SEvalZero 
33*10465441SEvalZero struct JEDEC_ID
34*10465441SEvalZero {
35*10465441SEvalZero     uint8_t manufacturer_id;          /* Manufacturer ID */
36*10465441SEvalZero     uint8_t density_code:5; /* Density Code */
37*10465441SEvalZero     uint8_t family_code:3;  /* Family Code */
38*10465441SEvalZero     uint8_t version_code:5; /* Product Version Code */
39*10465441SEvalZero     uint8_t mlc_code:3;     /* MLC Code */
40*10465441SEvalZero     uint8_t byte_count;     /* Byte Count */
41*10465441SEvalZero };
42*10465441SEvalZero 
43*10465441SEvalZero #define AT45DB_BUFFER_1_WRITE                 0x84
44*10465441SEvalZero #define AT45DB_BUFFER_2_WRITE                 0x87
45*10465441SEvalZero #define AT45DB_BUFFER_1_READ                  0xD4
46*10465441SEvalZero #define AT45DB_BUFFER_2_READ                  0xD6
47*10465441SEvalZero #define AT45DB_B1_TO_MM_PAGE_PROG_WITH_ERASE  0x83
48*10465441SEvalZero #define AT45DB_B2_TO_MM_PAGE_PROG_WITH_ERASE  0x86
49*10465441SEvalZero #define AT45DB_MM_PAGE_TO_B1_XFER             0x53
50*10465441SEvalZero #define AT45DB_MM_PAGE_TO_B2_XFER             0x55
51*10465441SEvalZero #define AT45DB_PAGE_ERASE                     0x81
52*10465441SEvalZero #define AT45DB_SECTOR_ERASE                   0x7C
53*10465441SEvalZero #define AT45DB_READ_STATE_REGISTER            0xD7
54*10465441SEvalZero #define AT45DB_MM_PAGE_READ                   0xD2
55*10465441SEvalZero #define AT45DB_MM_PAGE_PROG_THRU_BUFFER1      0x82
56*10465441SEvalZero #define AT45DB_CMD_JEDEC_ID                   0x9F
57*10465441SEvalZero 
58*10465441SEvalZero static struct spi_flash_at45dbxx  spi_flash_at45dbxx;
59*10465441SEvalZero 
60*10465441SEvalZero /*****************************************************************************/
61*10465441SEvalZero /*Status Register Format:                                   */
62*10465441SEvalZero /* ------------------------------------------------------------------------- */
63*10465441SEvalZero /* | bit7   | bit6   | bit5   | bit4   | bit3   | bit2   | bit1   | bit0   | */
64*10465441SEvalZero /* |--------|--------|--------|--------|--------|--------|--------|--------| */
65*10465441SEvalZero /* |RDY/BUSY| COMP   |         device density            |   X    |   X    | */
66*10465441SEvalZero /* ------------------------------------------------------------------------- */
67*10465441SEvalZero /* 0:busy   |        |        AT45DB041:0111             | protect|page size */
68*10465441SEvalZero /* 1:ready  |        |        AT45DB161:1011             |                   */
69*10465441SEvalZero /* --------------------------------------------------------------------------*/
70*10465441SEvalZero /*****************************************************************************/
AT45DB_StatusRegisterRead(void)71*10465441SEvalZero static uint8_t AT45DB_StatusRegisterRead(void)
72*10465441SEvalZero {
73*10465441SEvalZero     return rt_spi_sendrecv8(spi_flash_at45dbxx.rt_spi_device, AT45DB_READ_STATE_REGISTER);
74*10465441SEvalZero }
75*10465441SEvalZero 
wait_busy(void)76*10465441SEvalZero static void wait_busy(void)
77*10465441SEvalZero {
78*10465441SEvalZero     uint16_t i = 0;
79*10465441SEvalZero     while (i++ < 10000)
80*10465441SEvalZero     {
81*10465441SEvalZero         if (AT45DB_StatusRegisterRead() & 0x80)
82*10465441SEvalZero         {
83*10465441SEvalZero             return;
84*10465441SEvalZero         }
85*10465441SEvalZero     }
86*10465441SEvalZero     FLASH_TRACE("\r\nSPI_FLASH timeout!!!\r\n");
87*10465441SEvalZero }
88*10465441SEvalZero 
89*10465441SEvalZero /* RT-Thread Device Driver Interface */
AT45DB_flash_init(rt_device_t dev)90*10465441SEvalZero static rt_err_t AT45DB_flash_init(rt_device_t dev)
91*10465441SEvalZero {
92*10465441SEvalZero     return RT_EOK;
93*10465441SEvalZero }
94*10465441SEvalZero 
AT45DB_flash_open(rt_device_t dev,rt_uint16_t oflag)95*10465441SEvalZero static rt_err_t AT45DB_flash_open(rt_device_t dev, rt_uint16_t oflag)
96*10465441SEvalZero {
97*10465441SEvalZero 
98*10465441SEvalZero     return RT_EOK;
99*10465441SEvalZero }
100*10465441SEvalZero 
AT45DB_flash_close(rt_device_t dev)101*10465441SEvalZero static rt_err_t AT45DB_flash_close(rt_device_t dev)
102*10465441SEvalZero {
103*10465441SEvalZero     return RT_EOK;
104*10465441SEvalZero }
105*10465441SEvalZero 
AT45DB_flash_control(rt_device_t dev,int cmd,void * args)106*10465441SEvalZero static rt_err_t AT45DB_flash_control(rt_device_t dev, int cmd, void *args)
107*10465441SEvalZero {
108*10465441SEvalZero     RT_ASSERT(dev != RT_NULL);
109*10465441SEvalZero 
110*10465441SEvalZero     if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
111*10465441SEvalZero     {
112*10465441SEvalZero         struct rt_device_blk_geometry *geometry;
113*10465441SEvalZero 
114*10465441SEvalZero         geometry = (struct rt_device_blk_geometry *)args;
115*10465441SEvalZero         if (geometry == RT_NULL) return -RT_ERROR;
116*10465441SEvalZero 
117*10465441SEvalZero         geometry->bytes_per_sector = 512;
118*10465441SEvalZero         geometry->sector_count = 4096;
119*10465441SEvalZero         geometry->block_size = 4096; /* block erase: 4k */
120*10465441SEvalZero     }
121*10465441SEvalZero 
122*10465441SEvalZero     return RT_EOK;
123*10465441SEvalZero }
124*10465441SEvalZero 
AT45DB_flash_read_page_256(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)125*10465441SEvalZero static rt_size_t AT45DB_flash_read_page_256(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
126*10465441SEvalZero {
127*10465441SEvalZero     uint32_t index, nr;
128*10465441SEvalZero     uint8_t * read_buffer = buffer;
129*10465441SEvalZero     uint32_t  page = pos;
130*10465441SEvalZero 
131*10465441SEvalZero     nr = size;
132*10465441SEvalZero 
133*10465441SEvalZero     for (index = 0; index < nr; index++)
134*10465441SEvalZero     {
135*10465441SEvalZero         uint8_t send_buffer[8];
136*10465441SEvalZero         uint32_t i;
137*10465441SEvalZero 
138*10465441SEvalZero         for(i=0; i<sizeof(send_buffer); i++)
139*10465441SEvalZero         {
140*10465441SEvalZero             send_buffer[i] = 0;
141*10465441SEvalZero         }
142*10465441SEvalZero 
143*10465441SEvalZero         send_buffer[0] = AT45DB_MM_PAGE_READ;
144*10465441SEvalZero         send_buffer[1] = (uint8_t)(page >> 7);
145*10465441SEvalZero         send_buffer[2] = (uint8_t)(page << 1);
146*10465441SEvalZero 
147*10465441SEvalZero         rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 256);
148*10465441SEvalZero         read_buffer += 256;
149*10465441SEvalZero         page++;
150*10465441SEvalZero     }
151*10465441SEvalZero 
152*10465441SEvalZero     return size;
153*10465441SEvalZero }
154*10465441SEvalZero 
AT45DB_flash_read_page_512(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)155*10465441SEvalZero static rt_size_t AT45DB_flash_read_page_512(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
156*10465441SEvalZero {
157*10465441SEvalZero     uint32_t index, nr;
158*10465441SEvalZero     uint8_t * read_buffer = buffer;
159*10465441SEvalZero     uint32_t  page = pos;
160*10465441SEvalZero 
161*10465441SEvalZero     nr = size;
162*10465441SEvalZero 
163*10465441SEvalZero     for (index = 0; index < nr; index++)
164*10465441SEvalZero     {
165*10465441SEvalZero         uint8_t send_buffer[8];
166*10465441SEvalZero         uint32_t i;
167*10465441SEvalZero 
168*10465441SEvalZero         for(i=0; i<sizeof(send_buffer); i++)
169*10465441SEvalZero         {
170*10465441SEvalZero             send_buffer[i] = 0;
171*10465441SEvalZero         }
172*10465441SEvalZero 
173*10465441SEvalZero         send_buffer[0] = AT45DB_MM_PAGE_READ;
174*10465441SEvalZero         send_buffer[1] = (uint8_t)(page >> 6);
175*10465441SEvalZero         send_buffer[2] = (uint8_t)(page << 2);
176*10465441SEvalZero 
177*10465441SEvalZero         rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 512);
178*10465441SEvalZero         read_buffer += 512;
179*10465441SEvalZero         page++;
180*10465441SEvalZero     }
181*10465441SEvalZero 
182*10465441SEvalZero     return size;
183*10465441SEvalZero }
184*10465441SEvalZero 
AT45DB_flash_read_page_1024(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)185*10465441SEvalZero static rt_size_t AT45DB_flash_read_page_1024(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
186*10465441SEvalZero {
187*10465441SEvalZero     uint32_t index, nr;
188*10465441SEvalZero     uint8_t * read_buffer = buffer;
189*10465441SEvalZero     uint32_t  page = pos;
190*10465441SEvalZero 
191*10465441SEvalZero     nr = size;
192*10465441SEvalZero 
193*10465441SEvalZero     for (index = 0; index < nr; index++)
194*10465441SEvalZero     {
195*10465441SEvalZero         uint8_t send_buffer[8];
196*10465441SEvalZero         uint32_t i;
197*10465441SEvalZero 
198*10465441SEvalZero         for(i=0; i<sizeof(send_buffer); i++)
199*10465441SEvalZero         {
200*10465441SEvalZero             send_buffer[i] = 0;
201*10465441SEvalZero         }
202*10465441SEvalZero 
203*10465441SEvalZero         send_buffer[0] = AT45DB_MM_PAGE_READ;
204*10465441SEvalZero         send_buffer[1] = (uint8_t)(page >> 5);
205*10465441SEvalZero         send_buffer[2] = (uint8_t)(page << 3);
206*10465441SEvalZero 
207*10465441SEvalZero         rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 1024);
208*10465441SEvalZero         read_buffer += 1024;
209*10465441SEvalZero         page++;
210*10465441SEvalZero     }
211*10465441SEvalZero 
212*10465441SEvalZero     return size;
213*10465441SEvalZero }
214*10465441SEvalZero 
AT45DB_flash_write_page_256(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)215*10465441SEvalZero static rt_size_t AT45DB_flash_write_page_256(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
216*10465441SEvalZero {
217*10465441SEvalZero     rt_uint32_t index, nr;
218*10465441SEvalZero     const uint8_t * write_buffer = buffer;
219*10465441SEvalZero     uint32_t  page = pos;
220*10465441SEvalZero 
221*10465441SEvalZero     nr = size;
222*10465441SEvalZero 
223*10465441SEvalZero     for (index = 0; index < nr; index++)
224*10465441SEvalZero     {
225*10465441SEvalZero         uint8_t send_buffer[4];
226*10465441SEvalZero 
227*10465441SEvalZero         send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
228*10465441SEvalZero         send_buffer[1] = (uint8_t) (page >> 7);
229*10465441SEvalZero         send_buffer[2] = (uint8_t) (page << 1);
230*10465441SEvalZero         send_buffer[3] = 0;
231*10465441SEvalZero 
232*10465441SEvalZero         rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 256);
233*10465441SEvalZero 
234*10465441SEvalZero         write_buffer += 256;
235*10465441SEvalZero         page++;
236*10465441SEvalZero 
237*10465441SEvalZero         wait_busy();
238*10465441SEvalZero     }
239*10465441SEvalZero 
240*10465441SEvalZero     return size;
241*10465441SEvalZero }
242*10465441SEvalZero 
AT45DB_flash_write_page_512(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)243*10465441SEvalZero static rt_size_t AT45DB_flash_write_page_512(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
244*10465441SEvalZero {
245*10465441SEvalZero     rt_uint32_t index, nr;
246*10465441SEvalZero     const uint8_t * write_buffer = buffer;
247*10465441SEvalZero     uint32_t  page = pos;
248*10465441SEvalZero 
249*10465441SEvalZero     nr = size;
250*10465441SEvalZero 
251*10465441SEvalZero     for (index = 0; index < nr; index++)
252*10465441SEvalZero     {
253*10465441SEvalZero         uint8_t send_buffer[4];
254*10465441SEvalZero 
255*10465441SEvalZero         send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
256*10465441SEvalZero         send_buffer[1] = (uint8_t) (page >> 6);
257*10465441SEvalZero         send_buffer[2] = (uint8_t) (page << 2);
258*10465441SEvalZero         send_buffer[3] = 0;
259*10465441SEvalZero 
260*10465441SEvalZero         rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 512);
261*10465441SEvalZero 
262*10465441SEvalZero         write_buffer += 512;
263*10465441SEvalZero         page++;
264*10465441SEvalZero 
265*10465441SEvalZero         wait_busy();
266*10465441SEvalZero     }
267*10465441SEvalZero 
268*10465441SEvalZero     return size;
269*10465441SEvalZero }
270*10465441SEvalZero 
AT45DB_flash_write_page_1024(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)271*10465441SEvalZero static rt_size_t AT45DB_flash_write_page_1024(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
272*10465441SEvalZero {
273*10465441SEvalZero     rt_uint32_t index, nr;
274*10465441SEvalZero     const uint8_t * write_buffer = buffer;
275*10465441SEvalZero     uint32_t  page = pos;
276*10465441SEvalZero 
277*10465441SEvalZero     nr = size;
278*10465441SEvalZero 
279*10465441SEvalZero     for (index = 0; index < nr; index++)
280*10465441SEvalZero     {
281*10465441SEvalZero         uint8_t send_buffer[4];
282*10465441SEvalZero 
283*10465441SEvalZero         send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
284*10465441SEvalZero         send_buffer[1] = (uint8_t) (page >> 5);
285*10465441SEvalZero         send_buffer[2] = (uint8_t) (page << 3);
286*10465441SEvalZero         send_buffer[3] = 0;
287*10465441SEvalZero 
288*10465441SEvalZero         rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 1024);
289*10465441SEvalZero 
290*10465441SEvalZero         write_buffer += 1024;
291*10465441SEvalZero         page++;
292*10465441SEvalZero 
293*10465441SEvalZero         wait_busy();
294*10465441SEvalZero     }
295*10465441SEvalZero 
296*10465441SEvalZero     return size;
297*10465441SEvalZero }
298*10465441SEvalZero 
at45dbxx_init(const char * flash_device_name,const char * spi_device_name)299*10465441SEvalZero rt_err_t at45dbxx_init(const char * flash_device_name, const char * spi_device_name)
300*10465441SEvalZero {
301*10465441SEvalZero     struct rt_spi_device * rt_spi_device;
302*10465441SEvalZero     struct JEDEC_ID * JEDEC_ID;
303*10465441SEvalZero 
304*10465441SEvalZero     rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
305*10465441SEvalZero     if(rt_spi_device == RT_NULL)
306*10465441SEvalZero     {
307*10465441SEvalZero         FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
308*10465441SEvalZero         return -RT_ENOSYS;
309*10465441SEvalZero     }
310*10465441SEvalZero     spi_flash_at45dbxx.rt_spi_device = rt_spi_device;
311*10465441SEvalZero 
312*10465441SEvalZero     /* config spi */
313*10465441SEvalZero     {
314*10465441SEvalZero         struct rt_spi_configuration cfg;
315*10465441SEvalZero         cfg.data_width = 8;
316*10465441SEvalZero         cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 and 3 */
317*10465441SEvalZero         cfg.max_hz = 66000000; /* Atmel RapidS Serial Interface: 66MHz Maximum Clock Frequency */
318*10465441SEvalZero         rt_spi_configure(spi_flash_at45dbxx.rt_spi_device, &cfg);
319*10465441SEvalZero     }
320*10465441SEvalZero 
321*10465441SEvalZero     /* read JEDEC ID */
322*10465441SEvalZero     {
323*10465441SEvalZero         uint8_t cmd;
324*10465441SEvalZero         uint8_t id_recv[6];
325*10465441SEvalZero         JEDEC_ID = (struct JEDEC_ID *)id_recv;
326*10465441SEvalZero 
327*10465441SEvalZero         cmd = AT45DB_CMD_JEDEC_ID;
328*10465441SEvalZero         rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, &cmd, 1, id_recv, 6);
329*10465441SEvalZero 
330*10465441SEvalZero         /**< 1FH = Atmel */
331*10465441SEvalZero         /**< 001 = Atmel DataFlash */
332*10465441SEvalZero         if(JEDEC_ID->manufacturer_id != 0x1F || JEDEC_ID->family_code != 0x01)
333*10465441SEvalZero         {
334*10465441SEvalZero             FLASH_TRACE("Manufacturer’s ID or Memory Type error!\r\n");
335*10465441SEvalZero             FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
336*10465441SEvalZero             return -RT_ENOSYS;
337*10465441SEvalZero         }
338*10465441SEvalZero 
339*10465441SEvalZero         if(JEDEC_ID->density_code == DENSITY_CODE_011D)
340*10465441SEvalZero         {
341*10465441SEvalZero             /**< AT45DB011D Density Code : 00010 = 1-Mbit */
342*10465441SEvalZero             FLASH_TRACE("AT45DB011D detection\r\n");
343*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
344*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 512;     /* 1-Mbit / 8 / 256 = 512 */
345*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*2;    /* Block Erase (2-Kbytes) */
346*10465441SEvalZero         }
347*10465441SEvalZero         else if(JEDEC_ID->density_code == DENSITY_CODE_021D)
348*10465441SEvalZero         {
349*10465441SEvalZero             /**< AT45DB021D Density Code : 00011 = 2-Mbit */
350*10465441SEvalZero             FLASH_TRACE("AT45DB021D detection\r\n");
351*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
352*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 512*2;   /* 2-Mbit / 8 / 256 = 1024 */
353*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*2;    /* Block Erase (2-Kbytes) */
354*10465441SEvalZero         }
355*10465441SEvalZero         else if(JEDEC_ID->density_code == DENSITY_CODE_041D)
356*10465441SEvalZero         {
357*10465441SEvalZero             /**< AT45DB041D Density Code : 00100 = 4-Mbit */
358*10465441SEvalZero             FLASH_TRACE("AT45DB041D detection\r\n");
359*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
360*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 512*4;   /* 4-Mbit / 8 / 256 = 2048 */
361*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*2;    /* Block Erase (2-Kbytes) */
362*10465441SEvalZero         }
363*10465441SEvalZero         else if(JEDEC_ID->density_code == DENSITY_CODE_081D)
364*10465441SEvalZero         {
365*10465441SEvalZero             /**< AT45DB081D Density Code : 00101 = 8-Mbit */
366*10465441SEvalZero             FLASH_TRACE("AT45DB081D detection\r\n");
367*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
368*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 512*8;   /* 8-Mbit / 8 / 256 = 4096 */
369*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*2;    /* Block Erase (2-Kbytes) */
370*10465441SEvalZero         }
371*10465441SEvalZero         else if(JEDEC_ID->density_code == DENSITY_CODE_161D)
372*10465441SEvalZero         {
373*10465441SEvalZero             /**< AT45DB161D Density Code : 00110 = 16-Mbit */
374*10465441SEvalZero             FLASH_TRACE("AT45DB161D detection\r\n");
375*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 512; /* Page Erase (512 Bytes) */
376*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 256*16;  /* 16-Mbit / 8 / 512 = 4096 */
377*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*4;    /* Block Erase (4-Kbytes) */
378*10465441SEvalZero         }
379*10465441SEvalZero         else if(JEDEC_ID->density_code == DENSITY_CODE_321D)
380*10465441SEvalZero         {
381*10465441SEvalZero             /**< AT45DB321D Density Code : 00111 = 32-Mbit */
382*10465441SEvalZero             FLASH_TRACE("AT45DB321D detection\r\n");
383*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 512; /* Page Erase (512 Bytes) */
384*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 256*32;  /* 32-Mbit / 8 / 512 = 8192 */
385*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*4;    /* Block Erase (4-Kbytes) */
386*10465441SEvalZero         }
387*10465441SEvalZero         else if(JEDEC_ID->density_code == DENSITY_CODE_642D)
388*10465441SEvalZero         {
389*10465441SEvalZero             /**< AT45DB642D Density Code : 01000 = 64-Mbit */
390*10465441SEvalZero             FLASH_TRACE("AT45DB642D detection\r\n");
391*10465441SEvalZero             spi_flash_at45dbxx.geometry.bytes_per_sector = 1024; /* Page Erase (1 Kbyte) */
392*10465441SEvalZero             spi_flash_at45dbxx.geometry.sector_count = 128*64;   /* 64-Mbit / 8 / 1024 = 8192 */
393*10465441SEvalZero             spi_flash_at45dbxx.geometry.block_size = 1024*8;     /* Block Erase (8 Kbytes) */
394*10465441SEvalZero         }
395*10465441SEvalZero         else
396*10465441SEvalZero         {
397*10465441SEvalZero             FLASH_TRACE("Memory Capacity error!\r\n");
398*10465441SEvalZero             return -RT_ENOSYS;
399*10465441SEvalZero         }
400*10465441SEvalZero     }
401*10465441SEvalZero 
402*10465441SEvalZero     /* register device */
403*10465441SEvalZero     spi_flash_at45dbxx.flash_device.type    = RT_Device_Class_Block;
404*10465441SEvalZero     spi_flash_at45dbxx.flash_device.init    = AT45DB_flash_init;
405*10465441SEvalZero     spi_flash_at45dbxx.flash_device.open    = AT45DB_flash_open;
406*10465441SEvalZero     spi_flash_at45dbxx.flash_device.close   = AT45DB_flash_close;
407*10465441SEvalZero     spi_flash_at45dbxx.flash_device.control = AT45DB_flash_control;
408*10465441SEvalZero 
409*10465441SEvalZero     if(JEDEC_ID->density_code == DENSITY_CODE_642D)
410*10465441SEvalZero     {
411*10465441SEvalZero         spi_flash_at45dbxx.flash_device.read 	  = AT45DB_flash_read_page_1024;
412*10465441SEvalZero         spi_flash_at45dbxx.flash_device.write   = AT45DB_flash_write_page_1024;
413*10465441SEvalZero     }
414*10465441SEvalZero     else if(JEDEC_ID->density_code == DENSITY_CODE_161D
415*10465441SEvalZero             || JEDEC_ID->density_code == DENSITY_CODE_321D )
416*10465441SEvalZero     {
417*10465441SEvalZero         spi_flash_at45dbxx.flash_device.read 	  = AT45DB_flash_read_page_512;
418*10465441SEvalZero         spi_flash_at45dbxx.flash_device.write   = AT45DB_flash_write_page_512;
419*10465441SEvalZero     }
420*10465441SEvalZero     else
421*10465441SEvalZero     {
422*10465441SEvalZero         spi_flash_at45dbxx.flash_device.read 	  = AT45DB_flash_read_page_256;
423*10465441SEvalZero         spi_flash_at45dbxx.flash_device.write   = AT45DB_flash_write_page_256;
424*10465441SEvalZero     }
425*10465441SEvalZero 
426*10465441SEvalZero     /* no private */
427*10465441SEvalZero     spi_flash_at45dbxx.flash_device.user_data = RT_NULL;
428*10465441SEvalZero 
429*10465441SEvalZero     rt_device_register(&spi_flash_at45dbxx.flash_device, flash_device_name,
430*10465441SEvalZero                        RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
431*10465441SEvalZero 
432*10465441SEvalZero     return RT_EOK;
433*10465441SEvalZero }
434