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