NXP

NAND Flash K60 Using

2019-07-12 12:31发布

NAND Flash K60 Using

本系统使用了Freescale(NXP)的MK60D系列芯片+Keil的IDE编译环境+YANDLD编写的K60库

硬件接法

SPI Flash接法

程序

*初始化、读取芯片信息

/* 初始化SPI接口 */ SPI_QuickInit(SPI2_SCK_PD12_SOUT_PD13_SIN_PD14, kSPI_CPOL0_CPHA0, 30*1000*1000); /* 初始化片选*/ PORT_PinMuxConfig(HW_GPIOD, 15, kPinAlt2); /* SPI2_PCS1 */ /* 获取SPI-Flash信息 */ if(w25qxx_init(HW_SPI2, HW_SPI_CS1)) { printf("w25qxx device no found! "); } else { struct w25qxx_attr_t w25qxx; w25qxx_get_attr(&w25qxx); printf("%s(0x%X) detected! ", w25qxx.name, w25qxx.id); printf("total size:%dKB ", w25qxx.size/1024); printf("block size:%dKB ", w25qxx.block_size/1024); printf("sector size:%d ", w25qxx.sector_size); printf("page size:%d ", w25qxx.page_size); buf_size = sizeof(buf); block = w25qxx.size/buf_size; }
w25qxx_attr_t类型的结构体,在w25qxx.h中定义: struct w25qxx_attr_t { const char* name; uint32_t size; uint16_t id; uint32_t page_size; uint32_t sector_size; uint32_t block_size; };
w25qxx_init(HW_SPI2, HW_SPI_CS1)函数中包括SPI选择、SPI模式、SPI片选、w25qxx_probe()获取芯片的信息: //芯片初始化 int w25qxx_init(uint32_t instance, uint32_t cs) { w25_dev.spi_instance = instance; w25_dev.spi_cs = cs; SPI_CTARConfig(instance, HW_CTAR0, kSPI_CPOL0_CPHA0, 8, kSPI_MSB, 30*1000*1000); return w25qxx_probe(); } 再来看其中的w25qxx_probe()如何获取芯片信息: //芯片探测 static int w25qxx_probe(void) { uint32_t i; uint16_t id; uint8_t buf[2]; /* read id */ spi_xfer(W25X_ManufactDeviceID, kSPI_PCS_KeepAsserted); spi_xfer(0, kSPI_PCS_KeepAsserted); spi_xfer(0, kSPI_PCS_KeepAsserted); spi_xfer(0, kSPI_PCS_KeepAsserted); buf[0] = spi_xfer(0, kSPI_PCS_KeepAsserted); buf[1] = spi_xfer(0, kSPI_PCS_ReturnInactive); id = ((buf[0]<<8) + buf[1]); W25QXX_TRACE("ID:0x%X ", id); //see if we find a match for(i = 0; i< ARRAY_SIZE(w25qxx_tbl);i++) { if(w25qxx_tbl[i].id == id) { /* find a match */ w25_dev.attr = w25qxx_tbl[i]; w25qxx_power_up(); buf[0] = w25qxx_read_sr(); W25QXX_TRACE("SR:0x%X ", buf[0]); buf[0] = w25qxx_read_sr2(); W25QXX_TRACE("SR2:0x%X ", buf[0]); // enable full access to all memory regin, something like unlock chip. w25qxx_write_sr(0x00); return 0; } } return 1; } 通过: /* read id */ spi_xfer(W25X_ManufactDeviceID, kSPI_PCS_KeepAsserted); spi_xfer(0, kSPI_PCS_KeepAsserted); spi_xfer(0, kSPI_PCS_KeepAsserted); spi_xfer(0, kSPI_PCS_KeepAsserted); buf[0] = spi_xfer(0, kSPI_PCS_KeepAsserted); buf[1] = spi_xfer(0, kSPI_PCS_ReturnInactive); id = ((buf[0]<<8) + buf[1]); W25QXX_TRACE("ID:0x%X ", id); 获取芯片的ID信息,ID信息通过SPI访问芯片内部预先写好的寄存器 #define W25X_DeviceID 0xAB 然后根据ID查表,进行进一步匹配来获取芯片的其他信息: //W25系列芯片信息 static const struct w25qxx_attr_t w25qxx_tbl[] = { {"W25Q10", 128*1024, 0xEF10, 256, 4096, (64*1024)}, {"W25Q20", 256*1024, 0xEF11, 256, 4096, (64*1024)}, {"W25Q40", 512*1024, 0xEF12, 256, 4096, (64*1024)}, {"W25Q80", 1024*1024, 0xEF13, 256, 4096, (64*1024)}, {"W25Q16", 2048*1024, 0xEF14, 256, 4096, (64*1024)}, {"W25Q32", 4096*1024, 0xEF15, 256, 4096, (64*1024)}, {"W25Q64", 8192*1024, 0xEF16, 256, 4096, (64*1024)}, {"W25Q128", 16384*1024, 0xEF17, 256, 4096, (64*1024)}, };

读写Flash

预先设置两个buff,buf用来写入Flash,buf2用来读取Flash static uint8_t buf[4*512]; static uint8_t buf2[4*512]; 再对buf进行赋初值: for(j=0;jj++) { buf[j] = j % 0xFF; } 新建两个变量:block,buf_size uint32_t block,buf_size; buf_size = sizeof(buf); block = w25qxx.size/buf_size; 此处,block不是Flash的硬件Block,而是指将整个Flash根据Buf的大小,分为几块,故block = w25qxx.size/buf_size;
再写入数据,写入第3个block: w25qxx_write(3*block, buf, buf_size); 再读取数据,并显示: w25qxx_read(3*block, buf2, buf_size); for(j=0;jprintf("writeData %d:%d------",j,buf[j]); printf("readData %d:%d ",j,buf2[j]); }

效果:

这里写图片描述