0
\$\begingroup\$

for a couple of days i have been trying to write a C code that writes to a flash memory via SPI. I already have a code that writes characters into flash. Now i wanted to expand on it and write integer into flash. The problem is that it seems like i can't fully erase the flash memory array. Only the lower 8 bit are erased which is fine for characters but for integer it's a problem.

Here is what i am using:

An open-source platform that uses the RISC-V ISA: https://github.com/pulp-platform/pulpissimo

This is not exactly the SDK i am using, but all the relevant functions are the same: https://greenwaves-technologies.com/manuals/BUILD/PULP-OS/html/index.html

This flash memory: https://www.digikey.com/en/datasheets/cypress-semiconductor-corp/cypress-semiconductor-corp-download-s25fs128s256s

I am using a HDL simulation environment by Mentor Graphics for simulation.

This is my code:

#include <stdio.h>
#include <rt/rt_api.h>
#include <stdint.h>
#include <stdarg.h>

#define BUFFER_SIZE 32

typedef struct {
    rt_spim_t *device;
    int *tx_buffer;
    int *rx_buffer;
} spi_flash_t;

rt_spim_conf_t* spi_flash_init_cfg(){
  rt_spim_conf_t *conf = malloc(sizeof(rt_spim_conf_t));
  rt_spim_conf_init(conf);
  conf->max_baudrate = 1000000;
  conf->id = 0;
  conf->cs = 0;
  conf->phase = 1;
  conf->polarity = 1;
  conf->big_endian = 1;
  conf->wordsize = RT_SPIM_WORDSIZE_32;
  return conf;
}

spi_flash_t* spi_flash_open(rt_spim_conf_t *conf) {
  rt_spim_t *device = rt_spim_open(NULL, conf, NULL);
  spi_flash_t *flash = malloc(sizeof(spi_flash_t));
  flash->device = device;
  flash->tx_buffer = rt_alloc(RT_ALLOC_PERIPH, BUFFER_SIZE);
  flash->rx_buffer = rt_alloc(RT_ALLOC_PERIPH, BUFFER_SIZE);
  return flash;
}

void spi_flash_write_enable(spi_flash_t *flash){
  flash->tx_buffer[0] = 0x06;
  rt_spim_send(flash->device, flash->tx_buffer, 8, RT_SPIM_CS_AUTO, NULL);
}

void spi_flash_close(spi_flash_t *flash){
  rt_spim_close(flash->device, NULL);
}

char spi_flash_read_sr1(spi_flash_t *flash){
  flash->tx_buffer[0] = 0x05;
  rt_spim_send(flash->device, flash->tx_buffer, 8, RT_SPIM_CS_KEEP, NULL);
  rt_spim_receive(flash->device, flash->rx_buffer, 8, RT_SPIM_CS_AUTO, NULL);
  return flash->rx_buffer[0];
}

char spi_flash_read_sr2(spi_flash_t *flash){
  flash->tx_buffer[0] = 0x07;
  rt_spim_send(flash->device, flash->tx_buffer, 8, RT_SPIM_CS_KEEP, NULL);
  rt_spim_receive(flash->device, flash->rx_buffer, 8, RT_SPIM_CS_AUTO, NULL);
  return flash->rx_buffer[0];
}

void spi_flash_wait_sr1(spi_flash_t *flash){
  while(spi_flash_read_sr1(flash) & 0x1){
  }
}

void spi_flash_wait_sr2(spi_flash_t *flash){
  while(spi_flash_read_sr2(flash) & 0x1){
  }
}

void spi_flash_bulk_erase(spi_flash_t *flash){
  flash->tx_buffer[0] = 0x60;
  rt_spim_send(flash->device, flash->tx_buffer, 32, RT_SPIM_CS_NONE, NULL);
}

void spi_flash_write_test(spi_flash_t *flash, int* data){
  flash->tx_buffer[0] = 0x02;
  rt_spim_send(flash->device, flash->tx_buffer, 32, RT_SPIM_CS_KEEP, NULL);
  flash->tx_buffer[0] = data[0];
  flash->tx_buffer[1] = data[1];
  flash->tx_buffer[2] = data[2];
  flash->tx_buffer[3] = data[3];
  rt_spim_send(flash->device, flash->tx_buffer, (32*4), RT_SPIM_CS_AUTO, NULL);
}

int main()
{

  int data[] = {0xDEADBEEF, 0x11111111, 0x22222222, 0x33333333};

  rt_spim_conf_t *config = spi_flash_init_cfg();
  spi_flash_t *flash = spi_flash_open(config);

  spi_flash_write_enable(flash);
  spi_flash_bulk_erase(flash);
  spi_flash_wait_sr2(flash);

  spi_flash_write_enable(flash);
  spi_flash_write_test(flash, data);
  spi_flash_wait_sr1(flash);

  spi_flash_close(flash);

  return 0;
}

There is probably something super obvious and i'm too blind to see it, but i can't write integer into the flash memory. As i said it seems like the bulk erase only erases the lower 8 bit of every entry in the memory. After executing this code my flash memory looks like this:

000000ef

000000be

000000ad

000000de

00000011

00000011

00000011

00000011

00000022

00000022

00000022

00000022

00000033

00000033

00000033

00000033

000000ff

000000ff

000000ff

( ... )

I thought that maybe block protection was the reason for this, but turning it off (which i might have failed to do so) and reading the register to check if block protection is enabled (which i might have also failed to do correctly) both didn't help.

This is the first time i'm trying to do something like this and i am really struggling to find the mistake. I know this is quite a lot and very specific, but i would greatly appreciate any input that might help me solve this.

Thank you

\$\endgroup\$
0
\$\begingroup\$

Flash memory is block device. This means that minimal erasable unit is block. Block consists of several pages. Page is a minimal writable unit. It is impossible that erase command clear only lower bits of each entry. How you print data which is read from flash?

\$\endgroup\$
  • \$\begingroup\$ According to the manual there are different erase flash array commands (page 107+). Parameter 4-kB Secot Erase (20h or 21h) sets all the bits of a 4-kB parameter sector to 1 (all bytes are FFh). Sector Erase (D8h or DCh) sets all bits in the addressed sector to 1 (all bytes are FFh). Bulk Erase (60h or C7h) sets all bits to 1 (all bytes are FFh) inside the entire flash memory array. This is the one i am using. To get the data from flash i can either use my simulation environment to show me the contents of the flash memory, or use the rt_spim_receive function. \$\endgroup\$ – Laha Feb 20 '20 at 13:09
0
\$\begingroup\$

RT_SPIM_CS_NONE - Don't do anything with the chip select.

You use this for erase bulk. But if you check datasheet p.114 figure 92, chip select must be asserted during bulk erase.

\$\endgroup\$
  • \$\begingroup\$ I am not too sure i understand what you mean. Do you mean p.109 fig. 92? Changing chip select to either AUTO, KEEP or NONE did not help to solve the problem. \$\endgroup\$ – Laha Feb 20 '20 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.