@@ -65,6 +65,92 @@ LOG_MODULE_REGISTER(flash_stm32_qspi, CONFIG_FLASH_LOG_LEVEL);
65
65
/* In dual-flash mode, total size is twice the size of one flash component */
66
66
#define STM32_QSPI_DOUBLE_FLASH DT_PROP(DT_NODELABEL(quadspi), dual_flash)
67
67
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
+
68
154
#if STM32_QSPI_USE_DMA
69
155
static const uint32_t table_m_size [] = {
70
156
LL_DMA_MDATAALIGN_BYTE ,
@@ -580,7 +666,8 @@ static int flash_stm32_qspi_read(const struct device *dev, off_t addr,
580
666
return ret ;
581
667
}
582
668
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 )
584
671
{
585
672
QSPI_CommandTypeDef cmd = {
586
673
.InstructionMode = QSPI_INSTRUCTION_1_LINE ,
@@ -601,15 +688,16 @@ static int qspi_read_status_register(const struct device *dev, uint8_t reg_num,
601
688
return - EINVAL ;
602
689
}
603
690
604
- return qspi_read_access (dev , & cmd , reg , sizeof (* reg ));
691
+ return qspi_read_access (dev , & cmd , ( uint8_t * ) reg , sizeof (* reg ));
605
692
}
606
693
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 )
608
696
{
609
697
struct flash_stm32_qspi_data * dev_data = dev -> data ;
610
698
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 ;
613
701
int ret ;
614
702
615
703
QSPI_CommandTypeDef cmd = {
@@ -619,21 +707,21 @@ static int qspi_write_status_register(const struct device *dev, uint8_t reg_num,
619
707
};
620
708
621
709
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 )) ;
624
712
regs_p = & regs [0 ];
625
713
/* 1 byte write clears SR2, write SR2 as well */
626
714
if (dev_data -> qer_type == JESD216_DW15_QER_S2B1v1 ) {
627
715
ret = qspi_read_status_register (dev , 2 , & regs [1 ]);
628
716
if (ret < 0 ) {
629
717
return ret ;
630
718
}
631
- size = 2U ;
719
+ size += sizeof ( struct flash_reg ) ;
632
720
}
633
721
} else if (reg_num == 2U ) {
634
722
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 )) ;
637
725
regs_p = & regs [1 ];
638
726
/* if SR2 write needs SR1 */
639
727
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,
644
732
return ret ;
645
733
}
646
734
cmd .Instruction = SPI_NOR_CMD_WRSR ;
647
- size = 2U ;
735
+ size += sizeof ( struct flash_reg ) ;
648
736
regs_p = & regs [0 ];
649
737
}
650
738
} else if (reg_num == 3U ) {
651
739
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 )) ;
654
742
regs_p = & regs [2 ];
655
743
} else {
656
744
return - EINVAL ;
657
745
}
658
746
659
- return qspi_write_access (dev , & cmd , regs_p , size );
747
+ return qspi_write_access (dev , & cmd , ( uint8_t * ) regs_p , size );
660
748
}
661
749
662
750
static int qspi_wait_until_ready (const struct device * dev )
663
751
{
664
- uint8_t reg ;
752
+ struct flash_reg reg ;
665
753
int ret ;
666
754
667
755
do {
668
756
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 ));
670
758
671
759
return ret ;
672
760
}
@@ -1163,7 +1251,7 @@ static int qspi_program_addr_4b(const struct device *dev, bool write_enable)
1163
1251
1164
1252
static int qspi_write_enable (const struct device * dev )
1165
1253
{
1166
- uint8_t reg ;
1254
+ struct flash_reg reg ;
1167
1255
int ret ;
1168
1256
1169
1257
ret = qspi_send_cmd (dev , & cmd_write_en );
@@ -1173,7 +1261,7 @@ static int qspi_write_enable(const struct device *dev)
1173
1261
1174
1262
do {
1175
1263
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 ));
1177
1265
1178
1266
return ret ;
1179
1267
}
@@ -1183,7 +1271,7 @@ static int qspi_program_quad_io(const struct device *dev)
1183
1271
struct flash_stm32_qspi_data * data = dev -> data ;
1184
1272
uint8_t qe_reg_num ;
1185
1273
uint8_t qe_bit ;
1186
- uint8_t reg ;
1274
+ struct flash_reg reg ;
1187
1275
int ret ;
1188
1276
1189
1277
switch (data -> qer_type ) {
@@ -1218,18 +1306,18 @@ static int qspi_program_quad_io(const struct device *dev)
1218
1306
}
1219
1307
1220
1308
/* 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 )) {
1222
1310
return 0 ;
1223
1311
}
1224
1312
1225
- reg |= qe_bit ;
1313
+ flash_reg_set_for_all ( & reg , qe_bit ) ;
1226
1314
1227
1315
ret = qspi_write_enable (dev );
1228
1316
if (ret < 0 ) {
1229
1317
return ret ;
1230
1318
}
1231
1319
1232
- ret = qspi_write_status_register (dev , qe_reg_num , reg );
1320
+ ret = qspi_write_status_register (dev , qe_reg_num , & reg );
1233
1321
if (ret < 0 ) {
1234
1322
return ret ;
1235
1323
}
@@ -1245,8 +1333,9 @@ static int qspi_program_quad_io(const struct device *dev)
1245
1333
return ret ;
1246
1334
}
1247
1335
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 ));
1250
1339
return - EIO ;
1251
1340
}
1252
1341
0 commit comments