xref: /nrf52832-nimble/rt-thread/components/drivers/spi/spi_flash_gd.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2015-10-11     fullhan      copy from winbond flash
9  */
10 
11 #include <stdint.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 
15 #include "spi_flash.h"
16 #include "spi_flash_gd.h"
17 
18 #define FLASH_DEBUG
19 
20 #ifdef FLASH_DEBUG
21 #define FLASH_TRACE         rt_kprintf
22 #else
23 #define FLASH_TRACE(...)
24 #endif /* #ifdef FLASH_DEBUG */
25 
26 #define PAGE_SIZE           4096
27 
28 /* JEDEC Manufacturer's ID */
29 #define MF_ID           (0xC8)
30 /* JEDEC Device ID: Memory type and Capacity */
31 #define MTC_GD25Q128                (0x4018)
32 
33 /* command list */
34 #define CMD_WRSR                    (0x01)  /* Write Status Register */
35 #define CMD_PP                      (0x02)  /* Page Program */
36 #define CMD_READ                    (0x03)  /* Read Data */
37 #define CMD_WRDI                    (0x04)  /* Write Disable */
38 #define CMD_RDSR1                   (0x05)  /* Read Status Register-1 */
39 #define CMD_WREN                    (0x06)  /* Write Enable */
40 #define CMD_FAST_READ               (0x0B)  /* Fast Read */
41 #define CMD_ERASE_4K                (0x20)  /* Sector Erase:4K */
42 #define CMD_RDSR2                   (0x35)  /* Read Status Register-2 */
43 #define CMD_ERASE_32K               (0x52)  /* 32KB Block Erase */
44 #define CMD_JEDEC_ID                (0x9F)  /* Read JEDEC ID */
45 #define CMD_ERASE_full              (0xC7)  /* Chip Erase */
46 #define CMD_ERASE_64K               (0xD8)  /* 64KB Block Erase */
47 
48 #define DUMMY                       (0xFF)
49 
50 static struct spi_flash_device  spi_flash_device;
51 
flash_lock(struct spi_flash_device * flash_device)52 static void flash_lock(struct spi_flash_device * flash_device)
53 {
54     rt_mutex_take(&flash_device->lock, RT_WAITING_FOREVER);
55 }
56 
flash_unlock(struct spi_flash_device * flash_device)57 static void flash_unlock(struct spi_flash_device * flash_device)
58 {
59     rt_mutex_release(&flash_device->lock);
60 }
61 
w25qxx_read_status(void)62 static uint8_t w25qxx_read_status(void)
63 {
64     return rt_spi_sendrecv8(spi_flash_device.rt_spi_device, CMD_RDSR1);
65 }
66 
w25qxx_wait_busy(void)67 static void w25qxx_wait_busy(void)
68 {
69     while( w25qxx_read_status() & (0x01));
70 }
71 
72 /** \brief read [size] byte from [offset] to [buffer]
73  *
74  * \param offset uint32_t unit : byte
75  * \param buffer uint8_t*
76  * \param size uint32_t   unit : byte
77  * \return uint32_t byte for read
78  *
79  */
w25qxx_read(uint32_t offset,uint8_t * buffer,uint32_t size)80 static uint32_t w25qxx_read(uint32_t offset, uint8_t * buffer, uint32_t size)
81 {
82     uint8_t send_buffer[4];
83 
84     send_buffer[0] = CMD_WRDI;
85     rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
86 
87     send_buffer[0] = CMD_READ;
88     send_buffer[1] = (uint8_t)(offset>>16);
89     send_buffer[2] = (uint8_t)(offset>>8);
90     send_buffer[3] = (uint8_t)(offset);
91 
92     rt_spi_send_then_recv(spi_flash_device.rt_spi_device,
93                           send_buffer, 4,
94                           buffer, size);
95 
96     return size;
97 }
98 
99 /** \brief write N page on [page]
100  *
101  * \param page_addr uint32_t unit : byte (4096 * N,1 page = 4096byte)
102  * \param buffer const uint8_t*
103  * \return uint32_t
104  *
105  */
w25qxx_page_write(uint32_t page_addr,const uint8_t * buffer)106 static uint32_t w25qxx_page_write(uint32_t page_addr, const uint8_t* buffer)
107 {
108     uint32_t index;
109     uint8_t send_buffer[4];
110 
111     RT_ASSERT((page_addr&0xFF) == 0); /* page addr must align to 256byte. */
112 
113     send_buffer[0] = CMD_WREN;
114     rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
115 
116     send_buffer[0] = CMD_ERASE_4K;
117     send_buffer[1] = (page_addr >> 16);
118     send_buffer[2] = (page_addr >> 8);
119     send_buffer[3] = (page_addr);
120     rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 4);
121 
122     w25qxx_wait_busy(); // wait erase done.
123 
124     for(index=0; index < (PAGE_SIZE / 256); index++)
125     {
126         send_buffer[0] = CMD_WREN;
127         rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
128 
129         send_buffer[0] = CMD_PP;
130         send_buffer[1] = (uint8_t)(page_addr >> 16);
131         send_buffer[2] = (uint8_t)(page_addr >> 8);
132         send_buffer[3] = (uint8_t)(page_addr);
133 
134         rt_spi_send_then_send(spi_flash_device.rt_spi_device,
135                               send_buffer,
136                               4,
137                               buffer,
138                               256);
139 
140         buffer += 256;
141         page_addr += 256;
142         w25qxx_wait_busy();
143     }
144 
145     send_buffer[0] = CMD_WRDI;
146     rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
147 
148     return PAGE_SIZE;
149 }
150 
151 /* RT-Thread device interface */
w25qxx_flash_init(rt_device_t dev)152 static rt_err_t w25qxx_flash_init(rt_device_t dev)
153 {
154     return RT_EOK;
155 }
156 
w25qxx_flash_open(rt_device_t dev,rt_uint16_t oflag)157 static rt_err_t w25qxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
158 {
159     uint8_t send_buffer[3];
160 
161     flash_lock((struct spi_flash_device *)dev);
162 
163     send_buffer[0] = CMD_WREN;
164     rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
165 
166     send_buffer[0] = CMD_WRSR;
167     send_buffer[1] = 0;
168     send_buffer[2] = 0;
169     rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 3);
170 
171     w25qxx_wait_busy();
172 
173     flash_unlock((struct spi_flash_device *)dev);
174 
175     return RT_EOK;
176 }
177 
w25qxx_flash_close(rt_device_t dev)178 static rt_err_t w25qxx_flash_close(rt_device_t dev)
179 {
180     return RT_EOK;
181 }
182 
w25qxx_flash_control(rt_device_t dev,int cmd,void * args)183 static rt_err_t w25qxx_flash_control(rt_device_t dev, int cmd, void *args)
184 {
185     RT_ASSERT(dev != RT_NULL);
186 
187     if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
188     {
189         struct rt_device_blk_geometry *geometry;
190 
191         geometry = (struct rt_device_blk_geometry *)args;
192         if (geometry == RT_NULL) return -RT_ERROR;
193 
194         geometry->bytes_per_sector = spi_flash_device.geometry.bytes_per_sector;
195         geometry->sector_count = spi_flash_device.geometry.sector_count;
196         geometry->block_size = spi_flash_device.geometry.block_size;
197     }
198 
199     return RT_EOK;
200 }
201 
w25qxx_flash_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)202 static rt_size_t w25qxx_flash_read(rt_device_t dev,
203                                    rt_off_t pos,
204                                    void* buffer,
205                                    rt_size_t size)
206 {
207     flash_lock((struct spi_flash_device *)dev);
208 
209     w25qxx_read(pos*spi_flash_device.geometry.bytes_per_sector,
210                 buffer,
211                 size*spi_flash_device.geometry.bytes_per_sector);
212 
213     flash_unlock((struct spi_flash_device *)dev);
214 
215     return size;
216 }
217 
w25qxx_flash_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)218 static rt_size_t w25qxx_flash_write(rt_device_t dev,
219                                     rt_off_t pos,
220                                     const void* buffer,
221                                     rt_size_t size)
222 {
223     rt_size_t i = 0;
224     rt_size_t block = size;
225     const uint8_t * ptr = buffer;
226 
227     flash_lock((struct spi_flash_device *)dev);
228 
229     while(block--)
230     {
231         w25qxx_page_write((pos + i)*spi_flash_device.geometry.bytes_per_sector,
232                           ptr);
233         ptr += PAGE_SIZE;
234         i++;
235     }
236 
237     flash_unlock((struct spi_flash_device *)dev);
238 
239     return size;
240 }
241 
242 #ifdef RT_USING_DEVICE_OPS
243 const static struct rt_device_ops gd_device_ops =
244 {
245     w25qxx_flash_init,
246     w25qxx_flash_open,
247     w25qxx_flash_close,
248     w25qxx_flash_read,
249     w25qxx_flash_write,
250     w25qxx_flash_control
251 };
252 #endif
253 
gd_init(const char * flash_device_name,const char * spi_device_name)254 rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name)
255 {
256     struct rt_spi_device * rt_spi_device;
257 
258     /* initialize mutex */
259     if (rt_mutex_init(&spi_flash_device.lock, spi_device_name, RT_IPC_FLAG_FIFO) != RT_EOK)
260     {
261         rt_kprintf("init sd lock mutex failed\n");
262         return -RT_ENOSYS;
263     }
264 
265     rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
266     if(rt_spi_device == RT_NULL)
267     {
268         FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
269         return -RT_ENOSYS;
270     }
271     spi_flash_device.rt_spi_device = rt_spi_device;
272 
273     /* config spi */
274     {
275         struct rt_spi_configuration cfg;
276         cfg.data_width = 8;
277         cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
278         cfg.max_hz = 50 * 1000 * 1000; /* 50M */
279         rt_spi_configure(spi_flash_device.rt_spi_device, &cfg);
280     }
281 
282     /* init flash */
283     {
284         rt_uint8_t cmd;
285         rt_uint8_t id_recv[3];
286         uint16_t memory_type_capacity;
287 
288         flash_lock(&spi_flash_device);
289 
290         cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
291         rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
292 
293         cmd = CMD_WRDI;
294         rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
295 
296         /* read flash id */
297         cmd = CMD_JEDEC_ID;
298         rt_spi_send_then_recv(spi_flash_device.rt_spi_device, &cmd, 1, id_recv, 3);
299 
300         flash_unlock(&spi_flash_device);
301 
302         if(id_recv[0] != MF_ID)
303         {
304             FLASH_TRACE("Manufacturers ID error!\r\n");
305             FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
306             return -RT_ENOSYS;
307         }
308 
309         spi_flash_device.geometry.bytes_per_sector = 4096;
310         spi_flash_device.geometry.block_size = 4096; /* block erase: 4k */
311 
312         /* get memory type and capacity */
313         memory_type_capacity = id_recv[1];
314         memory_type_capacity = (memory_type_capacity << 8) | id_recv[2];
315 
316         if(memory_type_capacity == MTC_GD25Q128)
317         {
318             FLASH_TRACE("GD128 detection\r\n");
319             spi_flash_device.geometry.sector_count = 4096;
320         }
321         else
322         {
323             FLASH_TRACE("Memory Capacity error!\r\n");
324             return -RT_ENOSYS;
325         }
326     }
327 
328     /* register device */
329     spi_flash_device.flash_device.type    = RT_Device_Class_Block;
330 #ifdef RT_USING_DEVICE_OPS
331     spi_flash_device.flash_device.ops     = &gd_device_ops;
332 #else
333     spi_flash_device.flash_device.init    = w25qxx_flash_init;
334     spi_flash_device.flash_device.open    = w25qxx_flash_open;
335     spi_flash_device.flash_device.close   = w25qxx_flash_close;
336     spi_flash_device.flash_device.read    = w25qxx_flash_read;
337     spi_flash_device.flash_device.write   = w25qxx_flash_write;
338     spi_flash_device.flash_device.control = w25qxx_flash_control;
339 #endif
340     /* no private */
341     spi_flash_device.flash_device.user_data = RT_NULL;
342 
343     rt_device_register(&spi_flash_device.flash_device, flash_device_name,
344                        RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
345 
346     return RT_EOK;
347 }
348