10000 WIP: Python composable q/spi flash filesystems by andrewleech · Pull Request #5249 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

WIP: Python composable q/spi flash filesystems #5249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
4 changes: 2 additions & 2 deletions drivers/bus/softspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

#include "drivers/bus/spi.h"

int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
STATIC int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;

switch (cmd) {
Expand All @@ -44,7 +44,7 @@ int mp_soft_spi_ioctl(void *self_in, uint32_t cmd) {
return 0;
}

void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
STATIC void mp_soft_spi_transfer(void *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
mp_soft_spi_obj_t *self = (mp_soft_spi_obj_t*)self_in;
uint32_t delay_half = self->delay_half;

Expand Down
3 changes: 0 additions & 3 deletions drivers/bus/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,4 @@ typedef struct _mp_soft_spi_obj_t {

extern const mp_spi_proto_t mp_soft_spi_proto;

int mp_soft_spi_ioctl(void *self, uint32_t cmd);
void mp_soft_spi_transfer(void *self, size_t len, const uint8_t *src, uint8_t *dest);

#endif // MICROPY_INCLUDED_DRIVERS_BUS_SPI_H
80 changes: 37 additions & 43 deletions drivers/memory/spiflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,70 +51,64 @@
#define SECTOR_SIZE MP_SPIFLASH_ERASE_BLOCK_SIZE

STATIC void mp_spiflash_acquire_bus(mp_spiflash_t *self) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_ACQUIRE);
if (self->qspi_proto != NULL) {
self->qspi_proto->ioctl(self->data, MP_QSPI_IOCTL_BUS_ACQUIRE);
}
}

STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_RELEASE);
if (self->qspi_proto != NULL) {
self->qspi_proto->ioctl(self->data, MP_QSPI_IOCTL_BUS_RELEASE);
}
}

STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
if (self->spi_proto != NULL) {
// Note: len/data are unused for standard SPI
mp_hal_pin_write(c->bus.u_spi.cs, 0);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
mp_hal_pin_write(c->bus.u_spi.cs, 1);
mp_hal_pin_write(self->spi_cs, 0);
self->spi_proto->transfer(self->data, 1, &cmd, NULL);
mp_hal_pin_write(self->spi_cs, 1);
} else {
c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data);
self->qspi_proto->write_cmd_data(self->data, cmd, len, data);
}
}

STATIC void mp_spiflash_write_cmd_addr_data(mp_spiflash_t *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
if (self->spi_proto != NULL) {
uint8_t buf[4] = {cmd, addr >> 16, addr >> 8, addr};
mp_hal_pin_write(c->bus.u_spi.cs, 0);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL);
mp_hal_pin_write(self->spi_cs, 0);
self->spi_proto->transfer(self->data, 4, buf, NULL);
if (len) {
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, src, NULL);
self->spi_proto->transfer(self->data, len, src, NULL);
}
mp_hal_pin_write(c->bus.u_spi.cs, 1);
mp_hal_pin_write(self->spi_cs, 1);
} else {
c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src);
self->qspi_proto->write_cmd_addr_data(self->data, cmd, addr, len, src);
}
}

STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t len) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
if (self->spi_proto != NULL) {
uint32_t buf;
mp_hal_pin_write(c->bus.u_spi.cs, 0);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, (void*)&buf, (void*)&buf);
341A mp_hal_pin_write(c->bus.u_spi.cs, 1);
mp_hal_pin_write(self->spi_cs, 0);
self->spi_proto->transfer(self->data, 1, &cmd, NULL);
self->spi_proto->transfer(self->data, len, (void*)&buf, (void*)&buf);
mp_hal_pin_write(self->spi_cs, 1);
return buf;
} else {
return c->bus.u_qspi.proto->read_cmd(c->bus.u_qspi.data, cmd, len);
return self->qspi_proto->read_cmd(self->data, cmd, len);
}
}

STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
if (self->spi_proto != NULL) {
uint8_t buf[4] = {CMD_READ, addr >> 16, addr >> 8, addr};
mp_hal_pin_write(c->bus.u_spi.cs, 0);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL);
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, dest, dest);
mp_hal_pin_write(c->bus.u_spi.cs, 1);
mp_hal_pin_write(self->spi_cs, 0);
self->spi_proto->transfer(self->data, 4, buf, NULL);
self->spi_proto->transfer(self->data, len, dest, dest);
mp_hal_pin_write(self->spi_cs, 1);
} else {
c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, CMD_C4READ, addr, len, dest);
self->qspi_proto->read_cmd_qaddr_qdata(self->data, CMD_C4READ, addr, len, dest);
}
}

Expand Down Expand Up @@ -153,12 +147,12 @@ static inline void mp_spiflash_deepsleep_internal(mp_spiflash_t *self, int value
void mp_spiflash_init(mp_spiflash_t *self) {
self->flags = 0;

if (self->config->bus_kind == MP_SPIFLASH_BUS_SPI) {
mp_hal_pin_write(self->config->bus.u_spi.cs, 1);
mp_hal_pin_output(self->config->bus.u_spi.cs);
self->config->bus.u_spi.proto->ioctl(self->config->bus.u_spi.data, MP_SPI_IOCTL_INIT);
if (self->spi_proto != NULL) {
mp_hal_pin_write(self->spi_cs, 1);
mp_hal_pin_output(self->spi_cs);
self->spi_proto->ioctl(self->data, MP_SPI_IOCTL_INIT);
} else {
self->config->bus.u_qspi.proto->ioctl(self->config->bus.u_qspi.data, MP_QSPI_IOCTL_INIT);
self->qspi_proto->ioctl(self->data, MP_QSPI_IOCTL_INIT);
}

mp_spiflash_acquire_bus(self);
Expand All @@ -174,7 +168,7 @@ void mp_spiflash_init(mp_spiflash_t *self) {
}
#endif

if (self->config->bus_kind == MP_SPIFLASH_BUS_QSPI) {
if (self->qspi_proto != NULL) {
// Set QE bit
uint32_t data = (mp_spiflash_read_cmd(self, CMD_RDSR, 1) & 0xff)
| (mp_spiflash_read_cmd(self, CMD_RDCR, 1) & 0xff) << 8;
Expand Down Expand Up @@ -282,7 +276,7 @@ void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uin
return;
}
mp_spiflash_acquire_bus(self);
mp_spiflash_cache_t *cache = self->config->cache;
mp_spiflash_cache_t *cache = self->cache;
if (cache->user == self && cache->block != 0xffffffff) {
uint32_t bis = addr / SECTOR_SIZE;
uint32_t bie = (addr + len - 1) / SECTOR_SIZE;
Expand Down Expand Up @@ -325,7 +319,7 @@ STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {

self->flags &= ~1;

mp_spiflash_cache_t *cache = self->config->cache;
mp_spiflash_cache_t *cache = self->cache;

// Erase sector
int ret = mp_spiflash_erase_block_internal(self, cache->block * SECTOR_SIZE);
Expand Down Expand Up @@ -362,7 +356,7 @@ STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, siz
return -MP_EIO;
}

mp_spiflash_cache_t *cache = self->config->cache;
mp_spiflash_cache_t *cache = self->cache;

// Acquire the sector buffer
if (cache->user != self) {
Expand Down Expand Up @@ -435,7 +429,7 @@ int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, con

mp_spiflash_acquire_bus(self);

mp_spiflash_cache_t *cache = self->config->cache;
mp_spiflash_cache_t *cache = self->cache;
if (cache->user == self && bis <= cache->block && bie >= cache->block) {
// Write straddles current buffer
uint32_t pre;
Expand Down
30 changes: 8 additions & 22 deletions drivers/memory/spiflash.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,9 @@
#include "drivers/bus/spi.h"
#include "drivers/bus/qspi.h"

#ifndef MP_SPIFLASH_ERASE_BLOCK_SIZE
#define MP_SPIFLASH_ERASE_BLOCK_SIZE (4096) // must be a power of 2

enum {
MP_SPIFLASH_BUS_SPI,
MP_SPIFLASH_BUS_QSPI,
};
#endif

struct _mp_spiflash_t;

Expand All @@ -46,24 +43,13 @@ typedef struct _mp_spiflash_cache_t {
uint32_t block; // current block stored in buf; 0xffffffff if invalid
} mp_spiflash_cache_t;

typedef struct _mp_spiflash_config_t {
uint32_t bus_kind;
union {
struct {
mp_hal_pin_obj_t cs;
void *data;
const mp_spi_proto_t *proto;
} u_spi;
struct {
void *data;
const mp_qspi_proto_t *proto;
} u_qspi;
} bus;
mp_spiflash_cache_t *cache; // can be NULL if cache functions not used
} mp_spiflash_config_t;

typedef struct _mp_spiflash_t {
const mp_spiflash_config_t *config;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this config struct was separated out was so that it could be put in ROM, while the mp_spiflash_t struct was kept small and in RAM. What was your reason to combine them?

Copy link
Contributor Author
@andrewleech andrewleech Nov 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this early-on as I was still understanding the overall structure of spiflash subsystem, thinking it simplified things. For boards where the interfaces are hard-coded I can see how this makes sense though, probably better if I revert this change.

// define one of spi_proto or qspi_proto depending on type of bus.
const mp_spi_proto_t *spi_proto;
const mp_qspi_proto_t *qspi_proto;
void *data;
mp_hal_pin_obj_t spi_cs; // only needed for spi, not qspi
mp_spiflash_cache_t *cache; // can be NULL if cache functions not used
volatile uint32_t flags;
} mp_spiflash_t;

Expand Down
Loading
0