armink / SFUD

An using JEDEC's SFDP standard serial (SPI) flash universal driver library | 一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库
MIT License
1.25k stars 444 forks source link

新添加SPI的flash无法正常工作(BY25D16) #46

Open upupsky opened 3 years ago

upupsky commented 3 years ago

@armink 请帮忙看下这是什么问题呢. <00> info> app: Start initialize Serial Flash Universal Driver(SFUD) V1.1.0.
<00> info> app: You can get the latest version on https://github.com/armink/SFUD .
<00> info> app: The flash device manufacturer ID is 0x00, memory type ID is 0x00, capacity ID is 0xBD.
<00> info> app: Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P').
<00> info> app: Warning: Read SFDP parameter header information fail<info> app: Warning: This flash device is not found or not support.
<00> info> app: Error: BY25D16 flash device is initialize fail.

在SFUD_FLASH_CHIP_TABLE的末尾已经添加了{"BY25D16", SFUD_MF_ID_BOYA, 0x40, 0x15, 2L1024L1024L, SFUD_WM_PAGE_256B, 4096, 0x20},

感谢

armink commented 3 years ago

估计你没有定义这个宏吧 SFUD_USING_FLASH_INFO_TABLE

upupsky commented 3 years ago

您好,感谢您. 1、在sfud_cfg.h里面定义了宏SFUD_USING_FLASH_INFO_TABLE,整个文件内容如下: `#ifndef _SFUD_CFGH

define _SFUD_CFGH

define SFUD_DEBUG_MODE

define SFUD_USING_SFDP

define SFUD_USING_FLASH_INFO_TABLE

enum { SFUD_W25_DEVICE_INDEX = 0, };

//BY25D16 not support QSPI

define SFUD_FLASH_DEVICE_TABLE \

{ \ [SFUD_W25_DEVICE_INDEX] = {.name = "BY25D16", .spi.name = "SPI2"}, \ }

//#define SFUD_USING_QSPI

endif / _SFUD_CFGH /`

2、在sfud_port.c里面实现了spi_write_read函数,且通过之前的工程验证该函数读取写入flash是实现成功了的。文件代码如下: `

include

include

include "nrf_drv_spi.h"

include "my_spi.h"

include "flash_driver.h"

include "nrf_log.h"

include "nrf_delay.h"

static char log_buf[256];

void sfud_log_debug(const char file, const long line, const char format, ...);

static void spi_lock(const sfud_spi *spi) { //__disable_irq(); }

static void spi_unlock(const sfud_spi *spi) { //__enable_irq(); }

extern sfud_err spi_write_read(const sfud_spi spi, const uint8_t write_buf, size_t write_size, uint8_t *read_buf, size_t read_size); /**

//FLASH_CS_LOW();

for (size_t i = 0, retry_times; i < write_size + read_size; i++) {
    if (i < write_size) {
        send_data = *write_buf++;
    } else {
        send_data = SFUD_DUMMY_DATA;
    }

    retry_times = 1000;
            spi2_xfer_done = false;
    while(spi2_xfer_done == false){
        SFUD_RETRY_PROCESS(NULL, retry_times, result);
    }
    if (result != SFUD_SUCCESS) {
        goto exit;
    }
    //SPI_I2S_SendData(spi_dev->spix, send_data);
            SPI2_tx(&send_data,1);

    retry_times = 1000;
            spi2_xfer_done = false;
    while(spi2_xfer_done == false){
        SFUD_RETRY_PROCESS(NULL, retry_times, result);
    }
    if (result != SFUD_SUCCESS) {
        goto exit;
    }
    //read_data = SPI_I2S_ReceiveData(spi_dev->spix);
            SPI2_rx(&read_data,1);
    if (i >= write_size) {
        *read_buf++ = read_data;
    }
}

exit: //FLASH_CS_HIGH();

return result;

}

ifdef SFUD_USING_QSPI

/**

//delay function comes from LU. void delay_us(unsigned int us) { unsigned short int i=0; for(;us;us--) { for(i=5;i;i--); } }

/ about 100 microsecond delay / static void retry_delay_100us(void) { unsigned char i = 0; for(i = 0; i < 25; i++) { delay_us(4); } }

sfud_err sfud_spi_port_init(sfud_flash *flash) { sfud_err result = SFUD_SUCCESS;

/**
 * add your port spi bus and device object initialize code like this:
 * 1. rcc initialize
 * 2. gpio initialize
 * 3. spi device initialize
 * 4. flash->spi and flash->retry item initialize
 *    flash->spi.wr = spi_write_read; //Required
 *    flash->spi.qspi_read = qspi_read; //Required when QSPI mode enable
 *    flash->spi.lock = spi_lock;
 *    flash->spi.unlock = spi_unlock;
 *    flash->spi.user_data = &spix;
 *    flash->retry.delay = null;
 *    flash->retry.times = 10000; //Required
 */

    SPI2Init();
    nrf_gpio_cfg_output(FLASH_CS_PIN);

        /* set the interfaces and data */
        flash->spi.wr = spi_write_read;
        //flash->spi.qspi_read = NULL;
        flash->spi.lock = NULL;//spi_lock;
        flash->spi.unlock = NULL;//spi_unlock;
        flash->spi.user_data = NULL;
        /* about 100 microsecond delay */
        flash->retry.delay = retry_delay_100us;
        /* adout 60 seconds timeout */
        flash->retry.times = 60 * 10000;

return result;

}

/**

}

/**

} ` 感谢再次帮忙排查。

upupsky commented 3 years ago

1、sfud_spi_port_init接口中发现需要release powerdown(0xAB)后方可正常使用SFUD,不知其他flash是否存在这个问题。 2、spi_write_read接口中CS拉低后需要延迟10ms,这个可能是和PCB板走线有关系。

upupsky commented 3 years ago

3、建议集成poweroff和poweron。穿戴设备必备。1uA都是命。

armink commented 3 years ago

好像 poweroff 和 poweron 的命令处理方式在各个 flash 上都有些差异,这块你能确认一下其他 flash 对这块命令的对比情况吗?

upupsky commented 3 years ago

可以. 我回头多确认几个. 我估计也有人遇到这个问题.