diff options
| author | iabdalkader <i.abdalkader@gmail.com> | 2024-12-16 15:52:51 +0100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-04-09 00:22:32 +1000 |
| commit | 8807f8d01bc29d7c09a71a329877a1e8ad617fa8 (patch) | |
| tree | 610e36f05a625917ea5ee25093330cd30d0d23c2 | |
| parent | aec030004f019155334f56f61cf230fcf63ad759 (diff) | |
alif/ospi_flash: Configure dummy cycles.
The default dummy cycles may not match the actual flash frequency supported
by a certain board. For example, the MX chip uses 20 dummy cycles by
default which supports up to 200MHz DDR, but the maximum frequency
supported by the AE3 board is 50MHz DDR. So the dummy cycles for this
board can be as low as 6. It's important to set the correct dummy cycles,
as it results in doubling the XIP read speed, in the case of the AE3 board.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
| -rw-r--r-- | ports/alif/ospi_flash.c | 43 | ||||
| -rw-r--r-- | ports/alif/ospi_flash.h | 6 | ||||
| -rw-r--r-- | ports/alif/ospi_flash_settings.h | 6 |
3 files changed, 38 insertions, 17 deletions
diff --git a/ports/alif/ospi_flash.c b/ports/alif/ospi_flash.c index 8bffd6980..279227aa3 100644 --- a/ports/alif/ospi_flash.c +++ b/ports/alif/ospi_flash.c @@ -146,13 +146,19 @@ static uint32_t ospi_flash_read_id(ospi_flash_t *self) { /******************************************************************************/ // Functions specific to ISSI flash chips. -int ospi_flash_issi_octal_switch(ospi_flash_t *self) { - // Switch SPI flash to Octal DDR mode. +int ospi_flash_issi_init(ospi_flash_t *self) { const uint8_t cmd_wrvol = 0x81; + + // Configure dummy cycles. + ospi_flash_wren_spi(self); + uint8_t buf0[5] = {cmd_wrvol, 0, 0, 1, self->set->read_dummy_cycles}; + ospi_spi_transfer(&self->cfg, sizeof(buf0), buf0, buf0); + + // Switch SPI flash to Octal DDR mode. const uint8_t issi_mode_octal_ddr_dqs = 0xe7; ospi_flash_wren_spi(self); - uint8_t buf[5] = {cmd_wrvol, 0, 0, 0, issi_mode_octal_ddr_dqs}; - ospi_spi_transfer(&self->cfg, sizeof(buf), buf, buf); + uint8_t buf1[5] = {cmd_wrvol, 0, 0, 0, issi_mode_octal_ddr_dqs}; + ospi_spi_transfer(&self->cfg, sizeof(buf1), buf1, buf1); self->cfg.ddr_en = 1; return 0; } @@ -160,8 +166,7 @@ int ospi_flash_issi_octal_switch(ospi_flash_t *self) { /******************************************************************************/ // Functions specific to MX flash chips. -int ospi_flash_mx_octal_switch(ospi_flash_t *self) { - // Switch SPI flash to Octal SDR or DDR mode (SOPI or DOPI) by writing to CR2. +int ospi_flash_mx_init(ospi_flash_t *self) { const uint8_t cmd_wrcr2 = 0x72; const uint8_t mx_mode_enable_sopi = 0x01; const uint8_t mx_mode_enable_dopi = 0x02; @@ -171,9 +176,26 @@ int ospi_flash_mx_octal_switch(ospi_flash_t *self) { } else { mx_mode = mx_mode_enable_sopi; } + + // Configure dummy cycles. + uint8_t ddc_value = 0; + const uint8_t ospi_flash_mx_ddc[][2] = { + {20, 0}, {18, 1}, {16, 2}, {14, 3}, {12, 4}, {10, 5}, {8, 6}, {6, 7} + }; + for (size_t i = 0; i < MP_ARRAY_SIZE(ospi_flash_mx_ddc); i++) { + if (self->set->read_dummy_cycles == ospi_flash_mx_ddc[i][0]) { + ddc_value = ospi_flash_mx_ddc[i][1]; + break; + } + } ospi_flash_wren_spi(self); - uint8_t buf[6] = {cmd_wrcr2, 0, 0, 0, 0, mx_mode}; - ospi_spi_transfer(&self->cfg, sizeof(buf), buf, buf); + uint8_t buf0[6] = {cmd_wrcr2, 0, 0, 3, 0, ddc_value}; + ospi_spi_transfer(&self->cfg, sizeof(buf0), buf0, buf0); + + // Switch SPI flash to Octal SDR or DDR mode. + ospi_flash_wren_spi(self); + uint8_t buf1[6] = {cmd_wrcr2, 0, 0, 0, 0, mx_mode}; + ospi_spi_transfer(&self->cfg, sizeof(buf1), buf1, buf1); if (self->set->octal_mode == OSPI_FLASH_OCTAL_MODE_DDD) { self->cfg.ddr_en = 1; } else { @@ -310,8 +332,8 @@ int ospi_flash_init(void) { ospi_init(&self->cfg); // Switch to octal mode if needed. - if (set->octal_switch != NULL) { - set->octal_switch(self); + if (set->flash_init != NULL) { + set->flash_init(self); // Check the device ID after switching mode. if (ospi_flash_read_id(self) != set->jedec_id) { @@ -321,7 +343,6 @@ int ospi_flash_init(void) { // Enter XIP mode. It will be disabled during flash read/erase/write. ospi_flash_xip_enter(self); - return 0; } diff --git a/ports/alif/ospi_flash.h b/ports/alif/ospi_flash.h index 20846d447..39d270d7d 100644 --- a/ports/alif/ospi_flash.h +++ b/ports/alif/ospi_flash.h @@ -57,7 +57,7 @@ typedef struct _ospi_pin_settings_t { typedef struct _ospi_flash_settings_t { uint32_t jedec_id; uint32_t freq_hz; - int (*octal_switch)(struct _ospi_flash_t *); + int (*flash_init)(struct _ospi_flash_t *); uint8_t octal_mode; bool rxds; uint8_t inst_len; @@ -79,10 +79,10 @@ extern const ospi_flash_settings_t ospi_flash_settings[]; extern const size_t ospi_flash_settings_len; // Functions specific to ISSI flash chips. -int ospi_flash_issi_octal_switch(struct _ospi_flash_t *self); +int ospi_flash_issi_init(struct _ospi_flash_t *self); // Functions specific to MX flash chips. -int ospi_flash_mx_octal_switch(struct _ospi_flash_t *self); +int ospi_flash_mx_init(struct _ospi_flash_t *self); uint8_t ospi_flash_mx_read_cr(struct _ospi_flash_t *self); uint8_t ospi_flash_mx_read_cr2(struct _ospi_flash_t *self, uint32_t addr); int ospi_flash_mx_write_cr(struct _ospi_flash_t *self, uint8_t value); diff --git a/ports/alif/ospi_flash_settings.h b/ports/alif/ospi_flash_settings.h index c409f856d..c8605275c 100644 --- a/ports/alif/ospi_flash_settings.h +++ b/ports/alif/ospi_flash_settings.h @@ -31,7 +31,7 @@ // Macronix MX25 #define OSPI_FLASH_SETTINGS_MX25 \ - .octal_switch = ospi_flash_mx_octal_switch, \ + .flash_init = ospi_flash_mx_init, \ .octal_mode = OSPI_FLASH_OCTAL_MODE_DDD, \ .rxds = true, \ .inst_len = OSPI_INST_L_16bit, \ @@ -47,7 +47,7 @@ // Everspin EM. #define OSPI_FLASH_SETTINGS_EM \ - .octal_switch = ospi_flash_issi_octal_switch, \ + .flash_init = ospi_flash_issi_init, \ .octal_mode = OSPI_FLASH_OCTAL_MODE_DDD, \ .rxds = false, \ .inst_len = OSPI_INST_L_8bit, \ @@ -63,7 +63,7 @@ // ISSI IS25. #define OSPI_FLASH_SETTINGS_IS25 \ - .octal_switch = ospi_flash_issi_octal_switch, \ + .flash_init = ospi_flash_issi_init, \ .octal_mode = OSPI_FLASH_OCTAL_MODE_DDD, \ .rxds = true, \ .inst_len = OSPI_INST_L_8bit, \ |
