Página 1 de 1

memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 11:09
por Guri
Alguém pode me dar um "rumo" de como eu faço para Ler e escrever nessa inhonha:

SST26VF032B

Eu tô usando um ARM 407 para tal façanha, mas tô apanhando abeça. :)
Na verdade estou me preparando para começar a mexer, estive lendo o datasheet e caçando alguma rotina para testar, mas esta tudo ainda muito nebuloso. Ainda não peguei o fio da meada :D

Re: memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 12:30
por cfreund
Uso code abaixo para SST25VF016. Não sei se é compatível

Código: Selecionar todos
#define FLASH_SIZE         16777216
#define FLASH_SECTOR_SIZE  4096

typedef enum
{
    FLASH_PROTECT_NONE  = 0,
    FLASH_PROTECT_64KB  = 1,
    FLASH_PROTECT_128KB = 2,
    FLASH_PROTECT_256KB = 3,
    FLASH_PRTOECT_512KB = 4,
    FLASH_PROTECT_1MB   = 5,
    FLASH_PROTECT_2MB   = 6,
    FLASH_PROTECT_ALL   = 7
} FLASH_PROTECT_RANGE;


#define SST25VF_READ_DATA        0x03
#define SST25VF_FAST_READ_DATA   0x0B
#define SST25VF_SECTOR_ERASE     0x20
#define SST25VF_BLOCK_32_ERASE   0x52
#define SST25VF_BLOCK_64_ERASE   0xD8
#define SST25VF_BULK_ERASE       0xC7
#define SST25VF_BYTE_PROG        0x02
#define SST25VF_WORD_PROG        0xAD
#define SST25VF_READ_STATUS      0x05
#define SST25VF_WRITE_STATUS_EN  0x50
#define SST25VF_WRITE_STATUS     0x01
#define SST25VF_WRITE_EN         0x06
#define SST25VF_WRITE_DIS        0x04
#define SST25VF_READ_ID          0x9F
#define SST25VF_HW_WR_STATUS     0x70
#define SST25VF_POLL_WR_STATUS   0x80

#define FLASH_PROTECT_LOCK       0x80
#define FLASH_PROTECT_UNLOCK     0x00

#define FLASH_SELECT()           SERIAL_FLASH_ASSERT_CS_PIN()
#define FLASH_DESELECT()         SERIAL_FLASH_RELEASE_CS_PIN()
#define FLASH_CSOUTPUT()         SERIAL_FLASH_CFG_CS_PIN_OUT()

#define FLASH_ADDR_INVALID(addr) (addr >= FLASH_SIZE / 8)

static uint8_t sf_busy()
{
   return (serial_flash_getstatus() & 0x01);
}

static void sf_end()
{
    FLASH_DESELECT();
}

static void sf_send(uint8_t cmd, uint8_t end)
{
    while(sf_busy());

    FLASH_SELECT();
    spi1_put(cmd);
    if (end)
        sf_end();
}

static void sf_send_address(uint32_t addr)
{
    spi1_put(((addr >> 16) & 0xff));
    spi1_put(((addr >> 8) & 0xff));
    spi1_put((addr & 0xff));
}

static void sf_protect(FLASH_PROTECT_RANGE range)
{
   // Enable writes to the status register
   sf_send(SST25VF_WRITE_EN, true);

   // Unlock the protection bits
   sf_send(SST25VF_WRITE_STATUS, false);
   spi1_put(FLASH_PROTECT_UNLOCK);
   sf_end();

   // Enable writes to the status register
   sf_send(SST25VF_WRITE_EN, true);

   // Write the new protection bits and lock them
   sf_send(SST25VF_WRITE_STATUS, true);
   spi1_put(range | FLASH_PROTECT_LOCK);
   sf_end();
}

void serial_flash_init()
{
    FLASH_DESELECT();
    FLASH_CSOUTPUT();
    FLASH_DESELECT();
}

uint8_t serial_flash_getstatus()
{
    uint8_t status;
   
    FLASH_SELECT();
    spi1_put(SST25VF_READ_STATUS);
    status = spi1_put(SPI_DUMMY_DATA);
    FLASH_DESELECT();
   
    if (status == 0xFF)
        return 0;
   
    return status;
}

SERIAL_FLASH_STATUS serial_flash_setup()
{
    // Make sure chip is not in the write state
    sf_send(SST25VF_WRITE_DIS, 1);

    // Tell chip that we will poll the busy flag instead of using SDO
    sf_send(SST25VF_POLL_WR_STATUS, 1);
   
    sf_protect(FLASH_PROTECT_NONE);
   
   return RES_OK;
}

SERIAL_FLASH_STATUS serial_flash_get_id(SERIAL_FLASH_ID *flash_id)
{
    sf_send(SST25VF_READ_ID, 0);
    flash_id->manufacturer = spi1_put(SPI_DUMMY_DATA);
    flash_id->type = spi1_put(SPI_DUMMY_DATA);
    flash_id->capacity = spi1_put(SPI_DUMMY_DATA);
    sf_end();
   
   return RES_OK;
}

uint32_t serial_flash_getsize()
{
   return (FLASH_SIZE / 8);
}

SERIAL_FLASH_STATUS serial_flash_chip_erase()
{
    if (sf_busy())
       return RES_NOTRDY;
   
    sf_send(SST25VF_WRITE_EN, 1);
    sf_send(SST25VF_BULK_ERASE, 1);
   
    while (sf_busy());
   
    return RES_OK;
}

SERIAL_FLASH_STATUS serial_flash_sector_erase(uint32_t addr)
{
    if (FLASH_ADDR_INVALID(addr))
        return RES_EOF;
   
    if (sf_busy())
        return RES_NOTRDY;
   
    sf_send(SST25VF_WRITE_EN, 1);
   
    sf_send(SST25VF_SECTOR_ERASE, 0);
    sf_send_address(addr);
    sf_end();
   
    while (sf_busy());
   
    return RES_OK;
}

SERIAL_FLASH_STATUS serial_flash_read(uint32_t addr, void *src, uint16_t nbytes)
{
    uint8_t *d = src;
   
    if (FLASH_ADDR_INVALID(addr))
        return RES_EOF;
   
    if (nbytes < 1)
        return RES_PARERR;
   
    if (sf_busy())
        return RES_NOTRDY;
   
    sf_send(SST25VF_FAST_READ_DATA, 0);
    sf_send_address(addr);
    spi1_put(SPI_DUMMY_DATA);  // dummy byte necessary for fast read
    while(nbytes--)
        *d++ = spi1_put(SPI_DUMMY_DATA);
    sf_end();
   
   return RES_OK;
}

SERIAL_FLASH_STATUS serial_flash_write(uint32_t addr, void *dst, uint16_t nbytes)
{
    uint8_t word[2];
    uint8_t *d = dst;
   
    if (nbytes < 1)
        return RES_PARERR;
   
    if (FLASH_ADDR_INVALID(addr))
        return RES_EOF;
   
    if (sf_busy())
        return RES_NOTRDY;
   
    // Enable writing to the flash
    sf_send(SST25VF_WRITE_EN, true);
   
    // Do intial write separately to allow the rest of the writes
    // to be done as quickly as possible.
    word[0] = 0xFF;
    word[1] = 0xFF;
    if ((addr & 0x01) == 0)
    {
        word[0] = *d++;
        nbytes -= 1;
    }
   
    if (nbytes > 0)
    {
        word[1] = *d++;
        nbytes -= 1;
    }
   
    addr &= ~1;
    sf_send(SST25VF_WORD_PROG, false);
    sf_send_address(addr);
    spi1_put(word[0]);
    spi1_put(word[1]);
    sf_end();
   
    // Write remaining bytes
    while (nbytes)
    {
        word[0] = *d++;
        nbytes -= 1;

        if (nbytes > 0)
        {
            word[1] = *d++;
            nbytes -= 1;
        }
        else
            word[1] = 0xFF;

        sf_send(SST25VF_WORD_PROG, false);
        spi1_put(word[0]);
        spi1_put(word[1]);
        sf_end();
    }
   
    // Disable Writes
    sf_send(SST25VF_WRITE_DIS, true);
   
   return RES_OK;
}

Re: memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 20:42
por Guri
Obrigado Cfreund.

Caracas, quanta coisa para manipular essa memória, ufa.
Vou me debruçar sobre esse código e tentar entender a coisa.

:D Obrigado

Re: memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 21:37
por Guri
Desculpa a minha ignorância.

Mas você esta utilizando o drive de hardware (módulo SPI), né!

Re: memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 21:54
por cfreund
Sim, mas pode ser via software tb.

Re: memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 22:41
por Guri
Sim, entendi meu amigo.

Eu estou rodeando mexer com esse tipo de memória faz tempo, até comprei umas peças para brincar. Mas eu estou custando entender o modo como ela funciona, isso tá me deixando doido.

:mrgreen:

Re: memória Nor Flash da microchipa...

MensagemEnviado: 30 Ago 2021 23:43
por cfreund
Como assim? Dificuldade onde? Na interface?

Re: memória Nor Flash da microchipa...

MensagemEnviado: 31 Ago 2021 20:52
por Guri
cfreund escreveu:Como assim? Dificuldade onde? Na interface?


Eu sou grato cfreund, pela ilustração maravilhosa, :D

Eu vou estudar sua rotina, e fazer alguns testes, ler mais um pouco sobre essas memória seriais.
Obrigado de coração pela ajuda.