Skip to content

Commit 41e1688

Browse files
committed
alif/ospi_flash: Enter XIP mode when flash is idle.
Signed-off-by: Damien George <damien@micropython.org>
1 parent 84effb3 commit 41e1688

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

ports/alif/ospi_flash.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,14 @@ typedef struct _ospi_flash_t {
5050
const ospi_pin_settings_t *pin;
5151
const ospi_flash_settings_t *set;
5252
ospi_flash_cfg_t cfg;
53+
bool xip_active;
5354
} ospi_flash_t;
5455

5556
static ospi_flash_t global_flash;
5657

58+
static int ospi_flash_xip_enter(ospi_flash_t *self);
59+
static int ospi_flash_xip_exit(ospi_flash_t *self);
60+
5761
/******************************************************************************/
5862
// Generic SPI-flash helper functions.
5963

@@ -299,6 +303,34 @@ int ospi_flash_init(void) {
299303
}
300304
}
301305

306+
// Enter XIP mode. It will be disabled during flash read/erase/write.
307+
ospi_flash_xip_enter(self);
308+
309+
return 0;
310+
}
311+
312+
uintptr_t ospi_flash_get_xip_base(void) {
313+
ospi_flash_t *self = &global_flash;
314+
return (uintptr_t)self->cfg.xip_base;
315+
}
316+
317+
static int ospi_flash_xip_enter(ospi_flash_t *self) {
318+
if (!self->xip_active) {
319+
uint32_t irq_state = disable_irq();
320+
self->xip_active = true;
321+
ospi_xip_enter_16bit_cmd(&self->cfg, self->set->xip_data_len, self->set->read_command, self->set->read_command, self->set->read_dummy_cycles);
322+
enable_irq(irq_state);
323+
}
324+
return 0;
325+
}
326+
327+
static int ospi_flash_xip_exit(ospi_flash_t *self) {
328+
if (self->xip_active) {
329+
uint32_t irq_state = disable_irq();
330+
ospi_xip_exit_16bit_cmd(&self->cfg, self->set->read_command, self->set->read_command);
331+
self->xip_active = false;
332+
enable_irq(irq_state);
333+
}
302334
return 0;
303335
}
304336

@@ -308,21 +340,29 @@ int ospi_flash_init(void) {
308340
int ospi_flash_erase_sector(uint32_t addr) {
309341
ospi_flash_t *self = &global_flash;
310342

343+
ospi_flash_xip_exit(self);
344+
311345
ospi_flash_write_cmd(self, self->set->write_en);
312346
int ret = ospi_flash_wait_wel1(self);
313347
if (ret < 0) {
348+
ospi_flash_xip_enter(self);
314349
return ret;
315350
}
316351

317352
ospi_flash_write_cmd_addr(self, self->set->erase_command, OSPI_ADDR_L_32bit, addr);
353+
ret = ospi_flash_wait_wip0(self);
318354

319-
return ospi_flash_wait_wip0(self);
355+
ospi_flash_xip_enter(self);
356+
return ret;
320357
}
321358

322359
int ospi_flash_read(uint32_t addr, uint32_t len, uint8_t *dest) {
323360
// OSPI FIFO is limited to 256 bytes. Need DMA to get a longer read.
361+
// Note that direct reading is much faster than using XIP memory-mapped read.
324362
ospi_flash_t *self = &global_flash;
325363

364+
ospi_flash_xip_exit(self);
365+
326366
while (len) {
327367
uint32_t l = len / 4;
328368
if (l > 256) {
@@ -336,6 +376,7 @@ int ospi_flash_read(uint32_t addr, uint32_t len, uint8_t *dest) {
336376
dest += l * 4;
337377
}
338378

379+
ospi_flash_xip_enter(self);
339380
return 0;
340381
}
341382

@@ -365,6 +406,8 @@ static int ospi_flash_write_page(uint32_t addr, uint32_t len, const uint8_t *src
365406
}
366407

367408
int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src) {
409+
ospi_flash_xip_exit(&global_flash);
410+
368411
int ret = 0;
369412
uint32_t offset = addr & (PAGE_SIZE - 1);
370413
while (len) {
@@ -381,6 +424,8 @@ int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src) {
381424
src += rest;
382425
offset = 0;
383426
}
427+
428+
ospi_flash_xip_enter(&global_flash);
384429
return ret;
385430
}
386431

ports/alif/ospi_flash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ int ospi_flash_mx_write_cr2(struct _ospi_flash_t *self, uint32_t addr, uint8_t v
8888

8989
// SPI flash interface.
9090
int ospi_flash_init(void);
91+
uintptr_t ospi_flash_get_xip_base(void);
9192
int ospi_flash_erase_sector(uint32_t addr);
9293
int ospi_flash_read(uint32_t addr, uint32_t len, uint8_t *dest);
9394
int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src);

0 commit comments

Comments
 (0)