Arbitrary SPI Flash C model. With the scope of an SPI Flash driver unit test emulates this module SPI Flashes on logic level.
The model emulates an SPI Flash on logic level. As input are SPI packets used. In a real world application would be sent this SPI packet to the physically SPI core instead.
- No timing behavior
- emulated with WIP poll constant
Version | Date | Source | Change log |
---|---|---|---|
latest | latest.zip | ||
v0.1.0 | 2023-04-01 | v0.1.0.zip | initial draft |
The unittest gives a good flavor how to use the model.
To interact with the sfm (SPI Flash Model) are the following functions available.
Initializes the SFM and selects the emulated flash.
int sfm_init (t_sfm *self, char flashType[]);
Dumps Flash memory in hex values to console. Setting of start/stop -1
will print whole
memory content to console.
int sfm_dump (t_sfm *self, int32_t start, int32_t stop);
Stores flash model internal data buffer as file. Supported formats:
- .dif : difference to empty flash
0xff
in ascii-hex format
int sfm_store (t_sfm *self, char fileName[]);
Restore flash model internal data buffer from File. Supported formats:
- .dif : difference to empty flash
0xff
in ascii-hex format
int sfm_load (t_sfm *self, char fileName[]);
Compares SFM internal flash buffer with file. Supported formats:
- .dif : difference to empty flash
0xff
in ascii-hex format
int sfm_cmp (t_sfm *self, char fileName[]);
Access SPI Flash memory. SPI request and response are placed in the same SPI buffer variable.
int sfm (t_sfm *self, uint8_t* spi, uint32_t len);
The c
snippet below shows an minimal example to interact with the sfm. The variable spi represents
the packet sent to the SPI flash.
#include <stdlib.h> // EXIT codes, malloc
#include <stdio.h> // f.e. printf
#include <stdint.h> // defines fixed data types: int8_t...
#include "spi_flash_model.h" // function prototypes
int main ()
{
/* variables */
uint8_t spi[10]; // spi packet to interact with sfm
t_sfm spiFlash; // handle to SPI Flash
/* define used flash model */
sfm_init (&spiFlash, "W25Q16JV");
/* write enable */
spi[0] = 0x06; // W25Q16JV: write enable instruction
sfm (&spiFlash, spi, 1); // access flash model
/* write page */
spi[0] = 0x02; // W25Q16JV: write page instruction
spi[1] = 0x00; // address high byte
spi[2] = 0x00; // address middle byte
spi[3] = 0x00; // address low byte
spi[4] = 0x01; // data
spi[5] = 0x23;
spi[6] = 0x45;
spi[7] = 0x67;
spi[8] = 0x89;
spi[9] = 0xAB;
sfm (&spiFlash, spi, 10); // access flash model
// poll for WIP
for ( uint8_t i = 0; i < SFM_WIP_RETRY_IDLE; i++ ) {
spiLen = 2;
spi[0] = 0x05;
sfm(&spiFlash, spi, spiLen); // read state reg, needed for WIP poll
}
/* dump current flash content to check write */
sfm_dump (&spiFlash, 0x0, 0x10);
/* normal end */
exit(0);
}
This example compiled and executed leads to following output:
gcc -c -O spi_flash_model.c -o spi_flash_model.o
gcc -c -O main.c -o main.o
gcc spi_flash_model.o main.o -lm -o main
./main
00: 01 23 45 67 89 ab ff ff ff ff ff ff ff ff ff ff
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff