w25n01g的坏块管理代码

硬件环境: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中文件系统的操作

CSDN

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

半瓶醋的历史

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值