硬件环境:nrf52840 win10
winbond芯片:w25n01g
/*bad block management*/
typedef struct bblut_s {
uint16_t pba;//Physical Block Address”
uint16_t lba;//Logical Block Address
} bblut_t;
//you can reference (Read JEDEC ID) command
int8_t w25n01g_readBBLUT(flash_device_t *w25n01gc_flash, bblut_t *bblut, int lutsize)
{
spi_transfer_t spi_xfer_data;
int8_t status = FLASH_SUCCESS;
uint8_t in[4];
memset(&spi_xfer_data, 0, sizeof(spi_transfer_t));
status = w25n01gv_write_enable(w25n01gc_flash);
if (status != FLASH_SUCCESS)
{
return status;
}
/* Wait for busy bit */
status = wait_if_busy(w25n01gc_flash, W25N01GV_BUSY_DEFAULT_TIMEOUT_MS);
if (status != FLASH_SUCCESS)
{
if (status == FLASH_TIMEOUT)
{
LOG_FLASH(ERROR, "W25N01GV: %s, %d: wait if busy timeout!",
__func__, __LINE__);
}
else
{
LOG_FLASH(ERROR, "W25N01GV: %s, %d: wait if busy fail!", __func__,
__LINE__);
}
return status;
}
spi_xfer_data.opcode = W25N01GV_READ_BBM_LUT;
spi_xfer_data.dummy_cycles = 1;//W25N01GV_JEDEC_ID_DUMMY_CYCLES;
spi_xfer_data.dummy_cyles_pos = 0;
spi_xfer_data.rx_buf = in;
spi_xfer_data.rx_len = 4;
spi_xfer_data.tx_len = 0;
for(int i=0; i<lutsize; i++)
{
status = flash_spi_transfer(w25n01gc_flash, &spi_xfer_data);
if (status != FLASH_SUCCESS)
{
LOG_FLASH(ERROR, "W25N01GV: %s, %d: spi transfer failed", __func__,
__LINE__);
return status;
}
else
{
bblut[i].pba = (in[0] << 16)|in[1];
bblut[i].lba = (in[2] << 16)|in[3];
}
}
return status;
}
int8_t w25n01g_writeBBLUT(flash_device_t *w25n01gc_flash, uint16_t lba, uint16_t pba)
{
spi_transfer_t spi_xfer_data;
int8_t status = FLASH_SUCCESS;
uint8_t send_data[4] = {lba >> 8, lba, pba >> 8, pba};
memset(&spi_xfer_data, 0, sizeof(spi_transfer_t));
status = w25n01gv_write_enable(w25n01gc_flash);
if (status != FLASH_SUCCESS)
{
return status;
}
/* Wait for busy bit */
status = wait_if_busy(w25n01gc_flash, W25N01GV_BUSY_DEFAULT_TIMEOUT_MS);
if (status != FLASH_SUCCESS)
{
if (status == FLASH_TIMEOUT)
{
LOG_FLASH(ERROR, "W25N01GV: %s, %d: wait if busy timeout!",
__func__, __LINE__);
}
else
{
LOG_FLASH(ERROR, "W25N01GV: %s, %d: wait if busy fail!", __func__,
__LINE__);
}
return status;
}
spi_xfer_data.opcode = W25N01GV_JEDEC_ID;
spi_xfer_data.dummy_cycles = 0;//W25N01GV_JEDEC_ID_DUMMY_CYCLES;
spi_xfer_data.dummy_cyles_pos = 0;
//spi_xfer_data.rx_buf = in;
spi_xfer_data.rx_len = 0;
spi_xfer_data.tx_len = 0;
spi_xfer_data.tx_buf = send_data;
status = flash_spi_transfer(w25n01gc_flash, &spi_xfer_data);
if (status != FLASH_SUCCESS)
{
LOG_FLASH(ERROR, "W25N01GV: %s, %d: spi transfer failed", __func__,
__LINE__);
return status;
}
return status;
}
补充:很多人可能为了节省成本,而使用nand flash 这个推荐一篇博客:主要是nand flash中文件系统的操作