SFUD icon indicating copy to clipboard operation
SFUD copied to clipboard

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

Open upupsky opened this issue 5 years ago • 6 comments

@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},

感谢

upupsky avatar Jan 21 '21 16:01 upupsky

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

armink avatar Jan 22 '21 00:01 armink

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

#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_CFG_H */`

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

#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); /

  • SPI write data then read data */ /static/ 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) { sfud_err result = SFUD_SUCCESS; uint8_t send_data, read_data;

    /**

    • add your spi write and read code */ if (write_size) { SFUD_ASSERT(write_buf); } if (read_size) { SFUD_ASSERT(read_buf); }

//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 /**

  • read flash data by QSPI */ static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size) { sfud_err result = SFUD_SUCCESS;

    /**

    • add your qspi read flash data code */

    return result; } #endif /* 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;

}

/**

  • This function is print debug info.
  • @param file the file which has call this function
  • @param line the line number which has call this function
  • @param format output format
  • @param ... args */ void sfud_log_debug(const char *file, const long line, const char *format, ...) {

}

/**

  • This function is print routine info.
  • @param format output format
  • @param ... args */ void sfud_log_info(const char *format, ...) {

} ` 感谢再次帮忙排查。

upupsky avatar Jan 22 '21 01:01 upupsky

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

upupsky avatar Jan 22 '21 16:01 upupsky

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

upupsky avatar Jan 22 '21 17:01 upupsky

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

armink avatar Jan 23 '21 03:01 armink

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

upupsky avatar Jan 23 '21 13:01 upupsky