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