Skip to content

Commit 7f41f73

Browse files
committed
stm32/qspi: Don't require data reads and writes to be a multiple of 4.
Prior to this patch the QSPI driver assumed that the length of all data reads and writes was a multiple of 4. This patch allows any length. Reads are optimised for speed by using 32-bit transfers when possible, but writes always use a byte transfer because they only use a single data IO line and are relatively slow.
1 parent 34344a4 commit 7f41f73

1 file changed

Lines changed: 18 additions & 12 deletions

File tree

ports/stm32/qspi.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,12 @@ STATIC void qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr,
181181

182182
QUADSPI->AR = addr;
183183

184-
// Write out the data
184+
// Write out the data 1 byte at a time
185185
while (len) {
186186
while (!(QUADSPI->SR & QUADSPI_SR_FTF)) {
187187
}
188-
// TODO it seems that writes need to be 32-bit wide to start the xfer...
189-
//*(volatile uint8_t*)QUADSPI->DR = *src++;
190-
//--len;
191-
QUADSPI->DR = *(uint32_t*)src;
192-
src += 4;
193-
len -= 4;
188+
*(volatile uint8_t*)&QUADSPI->DR = *src++;
189+
--len;
194190
}
195191
}
196192

@@ -253,13 +249,23 @@ STATIC void qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr,
253249
QUADSPI->ABR = 0; // alternate byte: disable continuous read mode
254250
QUADSPI->AR = addr; // addres to read from
255251

256-
// Read in the data
252+
// Read in the data 4 bytes at a time if dest is aligned
253+
if (((uintptr_t)dest & 3) == 0) {
254+
while (len >= 4) {
255+
while (!(QUADSPI->SR & QUADSPI_SR_FTF)) {
256+
}
257+
*(uint32_t*)dest = QUADSPI->DR;
258+
dest += 4;
259+
len -= 4;
260+
}
261+
}
262+
263+
// Read in remaining data 1 byte at a time
257264
while (len) {
258-
while (!(QUADSPI->SR & QUADSPI_SR_FTF)) {
265+
while (!((QUADSPI->SR >> QUADSPI_SR_FLEVEL_Pos) & 0x3f)) {
259266
}
260-
*(uint32_t*)dest = QUADSPI->DR;
261-
dest += 4;
262-
len -= 4;
267+
*dest++ = *(volatile uint8_t*)&QUADSPI->DR;
268+
--len;
263269
}
264270

265271
QUADSPI->FCR = QUADSPI_FCR_CTCF; // clear TC flag

0 commit comments

Comments
 (0)