diff options
| -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, \ |
