@@ -65,6 +65,92 @@ LOG_MODULE_REGISTER(flash_stm32_qspi, CONFIG_FLASH_LOG_LEVEL);
6565/* In dual-flash mode, total size is twice the size of one flash component */
6666#define STM32_QSPI_DOUBLE_FLASH DT_PROP(DT_NODELABEL(quadspi), dual_flash)
6767
68+ #if STM32_QSPI_DOUBLE_FLASH
69+ #define FLASH_REG_FMT "%04x"
70+ #else
71+ #define FLASH_REG_FMT "%02x"
72+ #endif /* STM32_QSPI_DOUBLE_FLASH */
73+
74+ /*
75+ * A register of the flash device, such as a status register.
76+ *
77+ * When dual-flash mode is enabled, this structure contains the value of the actual register of both
78+ * flash memories. For example, if an instance of this structure is used to hold the value of the
79+ * status register, 'flash0_val' and 'flash1_val' will be equal respectively to the value of the
80+ * status register of the first and second flash memory.
81+ *
82+ * This structure is packed as it is directly sent/received over the QSPI bus.
83+ */
84+ struct flash_reg {
85+ uint8_t flash0_val ;
86+ #if STM32_QSPI_DOUBLE_FLASH
87+ uint8_t flash1_val ;
88+ #endif /* STM32_QSPI_DOUBLE_FLASH */
89+ } __packed ;
90+
91+ /*
92+ * Sets a bit in a flash register.
93+ *
94+ * In dual-flash mode, the value is updated for both flash memories.
95+ */
96+ static inline void flash_reg_set_for_all (struct flash_reg * reg , uint8_t bitmask )
97+ {
98+ reg -> flash0_val |= bitmask ;
99+ #if STM32_QSPI_DOUBLE_FLASH
100+ reg -> flash1_val |= bitmask ;
101+ #endif /* STM32_QSPI_DOUBLE_FLASH */
102+ }
103+
104+ /*
105+ * Checks if a bit is set in a flash register.
106+ *
107+ * In dual-flash mode, this routine returns true if and only if the bit is set for both flash
108+ * memories.
109+ */
110+ static inline bool flash_reg_is_set_for_all (struct flash_reg * reg , uint8_t bitmask )
111+ {
112+ bool is_set = (reg -> flash0_val & bitmask ) != 0U ;
113+
114+ #if STM32_QSPI_DOUBLE_FLASH
115+ is_set = is_set && ((reg -> flash1_val & bitmask ) != 0U );
116+ #endif /* STM32_QSPI_DOUBLE_FLASH */
117+
118+ return is_set ;
119+ }
120+
121+ /*
122+ * Checks if a bit is clear in a flash register.
123+ *
124+ * In dual-flash mode, this routine returns true if and only if the bit is clear for both flash
125+ * memories.
126+ */
127+ static inline bool flash_reg_is_clear_for_all (struct flash_reg * reg , uint8_t bitmask )
128+ {
129+ bool is_clear = (reg -> flash0_val & bitmask ) == 0U ;
130+
131+ #if STM32_QSPI_DOUBLE_FLASH
132+ is_clear = is_clear && ((reg -> flash1_val & bitmask ) == 0U );
133+ #endif /* STM32_QSPI_DOUBLE_FLASH */
134+
135+ return is_clear ;
136+ }
137+
138+ /*
139+ * Gets the raw representation of a flash register, as a uint16_t value where the lower byte is the
140+ * value for the first flash memory and the upper byte is the value for the second flash memory, if
141+ * any.
142+ */
143+ static inline uint16_t flash_reg_to_raw (const struct flash_reg * reg )
144+ {
145+ uint16_t raw = reg -> flash0_val ;
146+
147+ #if STM32_QSPI_DOUBLE_FLASH
148+ raw |= reg -> flash1_val << 8 ;
149+ #endif /* STM32_QSPI_DOUBLE_FLASH */
150+
151+ return raw ;
152+ }
153+
68154#if STM32_QSPI_USE_DMA
69155static const uint32_t table_m_size [] = {
70156 LL_DMA_MDATAALIGN_BYTE ,
@@ -580,7 +666,8 @@ static int flash_stm32_qspi_read(const struct device *dev, off_t addr,
580666 return ret ;
581667}
582668
583- static int qspi_read_status_register (const struct device * dev , uint8_t reg_num , uint8_t * reg )
669+ static int qspi_read_status_register (const struct device * dev , uint8_t reg_num ,
670+ struct flash_reg * reg )
584671{
585672 QSPI_CommandTypeDef cmd = {
586673 .InstructionMode = QSPI_INSTRUCTION_1_LINE ,
@@ -601,15 +688,16 @@ static int qspi_read_status_register(const struct device *dev, uint8_t reg_num,
601688 return - EINVAL ;
602689 }
603690
604- return qspi_read_access (dev , & cmd , reg , sizeof (* reg ));
691+ return qspi_read_access (dev , & cmd , ( uint8_t * ) reg , sizeof (* reg ));
605692}
606693
607- static int qspi_write_status_register (const struct device * dev , uint8_t reg_num , uint8_t reg )
694+ static int qspi_write_status_register (const struct device * dev , uint8_t reg_num ,
695+ struct flash_reg * reg )
608696{
609697 struct flash_stm32_qspi_data * dev_data = dev -> data ;
610698 size_t size ;
611- uint8_t regs [4 ] = { 0 };
612- uint8_t * regs_p ;
699+ struct flash_reg regs [4 ] = {0 };
700+ struct flash_reg * regs_p ;
613701 int ret ;
614702
615703 QSPI_CommandTypeDef cmd = {
@@ -619,21 +707,21 @@ static int qspi_write_status_register(const struct device *dev, uint8_t reg_num,
619707 };
620708
621709 if (reg_num == 1U ) {
622- size = 1U ;
623- regs [0 ] = reg ;
710+ size = sizeof ( struct flash_reg ) ;
711+ memcpy ( & regs [0 ], reg , sizeof ( struct flash_reg )) ;
624712 regs_p = & regs [0 ];
625713 /* 1 byte write clears SR2, write SR2 as well */
626714 if (dev_data -> qer_type == JESD216_DW15_QER_S2B1v1 ) {
627715 ret = qspi_read_status_register (dev , 2 , & regs [1 ]);
628716 if (ret < 0 ) {
629717 return ret ;
630718 }
631- size = 2U ;
719+ size += sizeof ( struct flash_reg ) ;
632720 }
633721 } else if (reg_num == 2U ) {
634722 cmd .Instruction = SPI_NOR_CMD_WRSR2 ;
635- size = 1U ;
636- regs [1 ] = reg ;
723+ size = sizeof ( struct flash_reg ) ;
724+ memcpy ( & regs [1 ], reg , sizeof ( struct flash_reg )) ;
637725 regs_p = & regs [1 ];
638726 /* if SR2 write needs SR1 */
639727 if ((dev_data -> qer_type == JESD216_DW15_QER_VAL_S2B1v1 ) ||
@@ -644,29 +732,29 @@ static int qspi_write_status_register(const struct device *dev, uint8_t reg_num,
644732 return ret ;
645733 }
646734 cmd .Instruction = SPI_NOR_CMD_WRSR ;
647- size = 2U ;
735+ size += sizeof ( struct flash_reg ) ;
648736 regs_p = & regs [0 ];
649737 }
650738 } else if (reg_num == 3U ) {
651739 cmd .Instruction = SPI_NOR_CMD_WRSR3 ;
652- size = 1U ;
653- regs [2 ] = reg ;
740+ size = sizeof ( struct flash_reg ) ;
741+ memcpy ( & regs [2 ], reg , sizeof ( struct flash_reg )) ;
654742 regs_p = & regs [2 ];
655743 } else {
656744 return - EINVAL ;
657745 }
658746
659- return qspi_write_access (dev , & cmd , regs_p , size );
747+ return qspi_write_access (dev , & cmd , ( uint8_t * ) regs_p , size );
660748}
661749
662750static int qspi_wait_until_ready (const struct device * dev )
663751{
664- uint8_t reg ;
752+ struct flash_reg reg ;
665753 int ret ;
666754
667755 do {
668756 ret = qspi_read_status_register (dev , 1 , & reg );
669- } while (!ret && ( reg & SPI_NOR_WIP_BIT ));
757+ } while (!ret && ! flash_reg_is_clear_for_all ( & reg , SPI_NOR_WIP_BIT ));
670758
671759 return ret ;
672760}
@@ -1163,7 +1251,7 @@ static int qspi_program_addr_4b(const struct device *dev, bool write_enable)
11631251
11641252static int qspi_write_enable (const struct device * dev )
11651253{
1166- uint8_t reg ;
1254+ struct flash_reg reg ;
11671255 int ret ;
11681256
11691257 ret = qspi_send_cmd (dev , & cmd_write_en );
@@ -1173,7 +1261,7 @@ static int qspi_write_enable(const struct device *dev)
11731261
11741262 do {
11751263 ret = qspi_read_status_register (dev , 1U , & reg );
1176- } while (!ret && !( reg & SPI_NOR_WEL_BIT ));
1264+ } while (!ret && !flash_reg_is_set_for_all ( & reg , SPI_NOR_WEL_BIT ));
11771265
11781266 return ret ;
11791267}
@@ -1183,7 +1271,7 @@ static int qspi_program_quad_io(const struct device *dev)
11831271 struct flash_stm32_qspi_data * data = dev -> data ;
11841272 uint8_t qe_reg_num ;
11851273 uint8_t qe_bit ;
1186- uint8_t reg ;
1274+ struct flash_reg reg ;
11871275 int ret ;
11881276
11891277 switch (data -> qer_type ) {
@@ -1218,18 +1306,18 @@ static int qspi_program_quad_io(const struct device *dev)
12181306 }
12191307
12201308 /* exit early if QE bit is already set */
1221- if (( reg & qe_bit ) != 0U ) {
1309+ if (flash_reg_is_set_for_all ( & reg , qe_bit )) {
12221310 return 0 ;
12231311 }
12241312
1225- reg |= qe_bit ;
1313+ flash_reg_set_for_all ( & reg , qe_bit ) ;
12261314
12271315 ret = qspi_write_enable (dev );
12281316 if (ret < 0 ) {
12291317 return ret ;
12301318 }
12311319
1232- ret = qspi_write_status_register (dev , qe_reg_num , reg );
1320+ ret = qspi_write_status_register (dev , qe_reg_num , & reg );
12331321 if (ret < 0 ) {
12341322 return ret ;
12351323 }
@@ -1245,8 +1333,9 @@ static int qspi_program_quad_io(const struct device *dev)
12451333 return ret ;
12461334 }
12471335
1248- if ((reg & qe_bit ) == 0U ) {
1249- LOG_ERR ("Status Register %u [0x%02x] not set" , qe_reg_num , reg );
1336+ if (!flash_reg_is_set_for_all (& reg , qe_bit )) {
1337+ LOG_ERR ("Status Register %u [0x" FLASH_REG_FMT "] not set" , qe_reg_num ,
1338+ flash_reg_to_raw (& reg ));
12501339 return - EIO ;
12511340 }
12521341
0 commit comments