//擦除扇区 static int w25qxx_erase_sector(uint32_t addr) { uint8_t buf_send[4]; addr /= W25X_SECTOR_SIZE; addr *= W25X_SECTOR_SIZE; //round addr to N x W25X_SECTOR_SIZE buf_send[0] = W25X_SectorErase; buf_send[1] = (uint8_t)((addr)>>16); buf_send[2] = (uint8_t)((addr)>>8); buf_send[3] = (uint8_t)addr; w25qxx_write_enable(); while((w25qxx_read_sr() & 0x01) == 0x01); spi_write(&device, buf_send, sizeof(buf_send), true); while((w25qxx_read_sr() & 0x01) == 0x01); return SPI_EOK; }
//芯片探测 static int w25qxx_probe(void) { uint32_t i; uint16_t id; uint8_t buf[2]; /* read id */ spi_xfer(W25X_ManufactDeviceID, W25QXX_CS_LOW); spi_xfer(0, W25QXX_CS_LOW); spi_xfer(0, W25QXX_CS_LOW); spi_xfer(0, W25QXX_CS_LOW); buf[0] = spi_xfer(0, W25QXX_CS_LOW); buf[1] = spi_xfer(0, W25QXX_CS_HIGH); id = ((buf[0]<<8) + buf[1]); W25QXX_TRACE("ID:0x%X\r\n", 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\r\n", buf[0]); buf[0] = w25qxx_read_sr2(); W25QXX_TRACE("SR2:0x%X\r\n", buf[0]); // enable full access to all memory regin, something like unlock chip. w25qxx_write_sr(0x00); return 0; } } return 1; }
//芯片探测 int w25qxx_probe(void) { uint32_t i; uint16_t id; uint8_t buf[4]; buf[0] = W25X_ManufactDeviceID; buf[1] = 0; buf[2] = 0; buf[3] = 0; /* read id */ spi_write(&device, buf, 4, false); spi_read(&device, buf, 2, true); id = ((buf[0]<<8) + buf[1]); W25QXX_TRACE("ID:%d\r\n", id); //see if we find a match for(i = 0; i< ARRAY_SIZE(w25qxx_attr_table);i++) { if(w25qxx_attr_table[i].id == id) { // find a match w25qxx_type.name = w25qxx_attr_table[i].name; w25qxx_type.id = w25qxx_attr_table[i].id; w25qxx_type.size = w25qxx_attr_table[i].size; w25qxx_power_up(); buf[0] = w25qxx_read_sr(); W25QXX_TRACE("SR:0x%X\r\n", buf[0]); buf[0] = w25qxx_read_sr2(); W25QXX_TRACE("SR2:0x%X\r\n", buf[0]); // enable full access to all memory regin, something like unlock chip. w25qxx_write_sr(0x00); return SPI_EOK; } } return SPI_ERROR; }
//擦除扇区 int w25qxx_erase_sector(uint32_t addr) { addr /= w25_dev.attr.sector_size; addr *= w25_dev.attr.sector_size; //round addr to N x W25X_SECTOR_SIZE w25qxx_write_enable(); while((w25qxx_read_sr() & 0x01) == 0x01); spi_xfer(W25X_SectorErase, W25QXX_CS_LOW); spi_xfer((uint8_t)((addr)>>16), W25QXX_CS_LOW); spi_xfer((uint8_t)((addr)>>8), W25QXX_CS_LOW); spi_xfer((uint8_t)addr, W25QXX_CS_HIGH); while((w25qxx_read_sr() & 0x01) == 0x01) { w25_dev.ops.delayms(10); } return 0; }
//写一页数据 static int w25qxx_write_page(uint32_t addr, uint8_t *buf, uint32_t len) { uint8_t buf_send[4]; w25qxx_write_enable(); buf_send[0] = W25X_PageProgram; buf_send[1] = (uint8_t)((addr)>>16); buf_send[2] = (uint8_t)((addr)>>8); buf_send[3] = (uint8_t)addr; if(spi_write(&device, buf_send, sizeof(buf_send), false)) { return SPI_ERROR; } spi_write(&device, buf, len, true); /* wait busy */ while((w25qxx_read_sr() & 0x01) == 0x01); return SPI_EOK; }
//写一页数据 int w25qxx_write_page(uint32_t addr, uint8_t *buf, uint32_t len) { w25qxx_write_enable(); /* send addr */ spi_xfer(W25X_PageProgram, W25QXX_CS_LOW); spi_xfer((uint8_t)((addr)>>16), W25QXX_CS_LOW); spi_xfer((uint8_t)((addr)>>8), W25QXX_CS_LOW); spi_xfer((uint8_t)addr, W25QXX_CS_LOW); w25_dev.ops.xfer(NULL, buf, len, W25QXX_CS_HIGH); while(w25_dev.ops.get_reamin() != 0) { w25_dev.ops.delayms(10); } /* wait busy */ while((w25qxx_read_sr() & 0x01) == 0x01) { w25_dev.ops.delayms(1); } return 0; }