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