pellepl / spiffs

Wear-leveled SPI flash file system for embedded devices
MIT License
1.52k stars 402 forks source link

error -10027 #275

Open jenya7 opened 3 years ago

jenya7 commented 3 years ago

My functions for AT45DB021

s32_t my_at45d_read(u32_t address, u32_t size, u8_t *buffer) { u32_t max_bytes_to_read; u32_t page; u32_t start_byte_on_page;

    // See if specified address is out of bounds
    if(address > AT45D_ADR_MAX)
   {
        return 0;
   }

  // See if "number of bytes to read" should be clipped
  max_bytes_to_read = AT45D_ADR_MAX - address + 1;
  if(size > max_bytes_to_read)
  {
      size = max_bytes_to_read;
  }

  while(!at45d_ready())
  {
     ;
  }

  // Select DataFlash
  spi_cs_lo();

  // Send command
  spi_wr_u8(AT45D_CMD_CONTINUOUS_ARRAY_READ);

    // Calculate page, offset and number of bytes remaining in page
    #if VAL_IS_PWR_OF_TWO(AT45D_PAGE_SIZE)
    page               = address >> 8;
    start_byte_on_page = address & 0xff;
    #else
    page               = address / AT45D_PAGE_SIZE;
    start_byte_on_page = address % AT45D_PAGE_SIZE;
    #endif

    // Send address
    at45d_tx_adr(page, start_byte_on_page);

    // Send dont-care bits
    spi_wr_u8(0x00);
    spi_wr_u8(0x00);
    spi_wr_u8(0x00);
    spi_wr_u8(0x00);

    // Read data
    spi_rd_data(buffer, size);

    // Deselect DataFlash
    spi_cs_hi();

    return size;
}

s32_t my_at45d_write(u32_t address, u32_t size, u8_t *buffer)
{
    uint32_t max_bytes_to_read;
    uint32_t start_page, last_page=0, this_page, pages;
    uint32_t start_byte_in_page;
    uint32_t last_page_bytes;
    uint32_t write_chunk;

    // See if specified address is out of bounds
    if(address > AT45D_ADR_MAX)
    {
        return 0;
    }

    max_bytes_to_read = AT45D_ADR_MAX - address + 1;
    if(size > max_bytes_to_read)
    {
       size = max_bytes_to_read;
    }

    #if VAL_IS_PWR_OF_TWO(AT45D_PAGE_SIZE)
    start_page         = address >> 8;
    start_byte_in_page = address & 0xff;
    pages = size >> 8;
    #else
    start_page        = address / AT45D_PAGE_SIZE;
    start_byte_in_page = address % AT45D_PAGE_SIZE;
    pages = size / AT45D_PAGE_SIZE;
    #endif

    last_page_bytes = size % AT45D_PAGE_SIZE;

    if (last_page_bytes)
        pages++;

    last_page = pages-1;

    for (this_page = start_page; this_page < pages; this_page++)
    {
        if (this_page == start_page)
        {
            write_chunk = AT45D_PAGE_SIZE - start_byte_in_page;
            at45d_wr_page_offset(buffer, this_page, start_byte_in_page, write_chunk);
            buffer += write_chunk;
        }
        else if (this_page == last_page)
        {
            at45d_wr_page_offset(buffer, this_page, 0, last_page_bytes);
        }
        else
        {
            at45d_wr_page(buffer, this_page);
            buffer += AT45D_PAGE_SIZE;
        }
    }

    // Set flag to busy
    at45d_ready_flag = 0;

    return 1;
}

s32_t my_at45d_erase(u32_t address, u32_t size)
{
    uint32_t start_page, next_page, pages;
    uint32_t last_page_bytes;

    #if VAL_IS_PWR_OF_TWO(AT45D_PAGE_SIZE)
    start_page         = address >> 8;
    pages = size >> 8;
    #else
    start_page        = address / AT45D_PAGE_SIZE;
    pages = size / AT45D_PAGE_SIZE;
    #endif

    last_page_bytes = size % AT45D_PAGE_SIZE;
    if (last_page_bytes)
        pages++;

    for (next_page = start_page; next_page < pages; next_page++)
    {
         at45d_erase_page(next_page);
    }

    return 0;
}

And setup int SPIFFS_Setup(void) { spiffs_config cfg;

    #if !SPIFFS_SINGLETON
    cfg.phys_size =   (250 * 1024); //250Kbyte                 //2*1024*1024; // use all spi flash
    cfg.phys_addr = 0; // start spiffs at start of spi flash
    cfg.phys_erase_block = LOG_PAGE_SIZE * 8; // according to datasheet 2k-2048
    cfg.log_block_size = LOG_PAGE_SIZE * 8;
    cfg.log_page_size = LOG_PAGE_SIZE;
    #endif
    cfg.hal_read_f = my_at45d_read;
    cfg.hal_write_f = my_at45d_write;
    cfg.hal_erase_f = my_at45d_erase;

    int res = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds,
              sizeof(spiffs_fds), spiffs_cache_buf, sizeof(spiffs_cache_buf), 0);
    //printf("mount res: %i\n", res);

    if (res != SPIFFS_OK)
    {
        res = SPIFFS_errno(&fs);
        if (res == SPIFFS_ERR_NOT_A_FS)
        {
            res = SPIFFS_format(&fs);
            if (res != SPIFFS_OK)
            {
                 //SEGGER_RTT_printf("SPIFFS format failed: %d\n", SPIFFS_errno(&fs));
                at45d_chip_erase();
                Delay_ms(6000);
                res = SPIFFS_format(&fs);

            }
            else
            {
                res = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds,
                      sizeof(spiffs_fds), spiffs_cache_buf, sizeof(spiffs_cache_buf), 0);
            }
        }
    }
    else
    {
        SPIFFS_unmount(&fs);
        res = SPIFFS_format(&fs);  //HERE I GET AN ERROR
        res = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds,
                              sizeof(spiffs_fds), spiffs_cache_buf, sizeof(spiffs_cache_buf), 0);

    }

    return res;
  }

On res = SPIFFS_format(&fs); I get an error - SPIFFS_ERR_ERASE_FAIL (-10027)

What could be a problem?

jenya7 commented 3 years ago

ok. I found the problem. Now res = SPIFFS_format(&fs); returns SPIFFS_OK. But here spiffs_file fd = SPIFFS_open(&fs, path, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); i get SPIFFS_ERR_FULL (-10001). What's the problem?