From 92f056d58f74cfd3986aaef1eea08f4f948fe03a Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 6 Feb 2025 10:14:34 +0100 Subject: [PATCH] alif/ospi_flash: Add 16-bit words swap flash setting. The byte order (endianness) seems to be swapped when read in 8D-8D-8D in XIP mode, for most flashes, with the exception of MX which seems to swap half-words. This commit adds a flash setting to allow parts to enable half-word swap when data is written, to fix this issue. By default, only endianness is fixed. Tested with both MX and ISSI parts on AE3, flash test and simple file write/read. Signed-off-by: iabdalkader --- ports/alif/ospi_flash.c | 12 ++++++++++-- ports/alif/ospi_flash.h | 1 + ports/alif/ospi_flash_settings.h | 5 ++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ports/alif/ospi_flash.c b/ports/alif/ospi_flash.c index 7400a678b2..f2f95a04cf 100644 --- a/ports/alif/ospi_flash.c +++ b/ports/alif/ospi_flash.c @@ -414,8 +414,16 @@ static int ospi_flash_write_page(uint32_t addr, uint32_t len, const uint8_t *src ospi_push(&self->cfg, addr); const uint32_t *src32 = (const uint32_t *)src; - for (; len; len -= 4) { - ospi_push(&self->cfg, __ROR(*src32++, 16)); + if (self->set->bswap16) { + // MX flashes swap 16-bit words when read in 8D-8D-8D. + for (; len; len -= 4) { + ospi_push(&self->cfg, __ROR(*src32++, 16)); + } + } else { + // For the rest of the flashes, we just correct the endianness. + for (; len; len -= 4) { + ospi_push(&self->cfg, __REV(*src32++)); + } } ospi_writel((&self->cfg), ser, self->cfg.ser); diff --git a/ports/alif/ospi_flash.h b/ports/alif/ospi_flash.h index 0095ee2d42..f909f4a43c 100644 --- a/ports/alif/ospi_flash.h +++ b/ports/alif/ospi_flash.h @@ -61,6 +61,7 @@ typedef struct _ospi_flash_settings_t { int (*flash_init)(struct _ospi_flash_t *); uint8_t octal_mode; bool rxds; + bool bswap16; uint8_t inst_len; uint8_t xip_data_len; uint16_t read_sr; diff --git a/ports/alif/ospi_flash_settings.h b/ports/alif/ospi_flash_settings.h index c8605275cd..72403c26b6 100644 --- a/ports/alif/ospi_flash_settings.h +++ b/ports/alif/ospi_flash_settings.h @@ -34,6 +34,7 @@ .flash_init = ospi_flash_mx_init, \ .octal_mode = OSPI_FLASH_OCTAL_MODE_DDD, \ .rxds = true, \ + .bswap16 = true, \ .inst_len = OSPI_INST_L_16bit, \ .xip_data_len = OSPI_DATA_L_16bit, \ .read_sr = 0x05fa, \ @@ -50,6 +51,7 @@ .flash_init = ospi_flash_issi_init, \ .octal_mode = OSPI_FLASH_OCTAL_MODE_DDD, \ .rxds = false, \ + .bswap16 = false, \ .inst_len = OSPI_INST_L_8bit, \ .xip_data_len = OSPI_DATA_L_16bit, \ .read_sr = 0x05, \ @@ -65,7 +67,8 @@ #define OSPI_FLASH_SETTINGS_IS25 \ .flash_init = ospi_flash_issi_init, \ .octal_mode = OSPI_FLASH_OCTAL_MODE_DDD, \ - .rxds = true, \ + .rxds = false, \ + .bswap16 = false, \ .inst_len = OSPI_INST_L_8bit, \ .xip_data_len = OSPI_DATA_L_16bit, \ .read_sr = 0x05, \