diff --git a/src/include/platform_support.h b/src/include/platform_support.h index 5e04ceb332b..91aa6463af0 100644 --- a/src/include/platform_support.h +++ b/src/include/platform_support.h @@ -77,6 +77,7 @@ bool platform_spi_deinit(spi_bus_e bus); bool platform_spi_chip_select(uint8_t device_select); uint8_t platform_spi_xfer(spi_bus_e bus, uint8_t value); +void platform_spi_xfer_block(spi_bus_e bus, uint8_t *const data, size_t count); #endif #ifdef PLATFORM_IDENT_DYNAMIC diff --git a/src/platforms/common/blackpill-f4/blackpill-f4.c b/src/platforms/common/blackpill-f4/blackpill-f4.c index 1e26b875770..0f0f49993e7 100644 --- a/src/platforms/common/blackpill-f4/blackpill-f4.c +++ b/src/platforms/common/blackpill-f4/blackpill-f4.c @@ -291,6 +291,48 @@ uint8_t platform_spi_xfer(const spi_bus_e bus, const uint8_t value) } } +void platform_spi_xfer_block(const spi_bus_e bus, uint8_t *const data, const size_t count) +{ + uint32_t spi_base = OB_SPI; + switch (bus) { + case SPI_BUS_INTERNAL: + spi_base = OB_SPI; + break; + case SPI_BUS_EXTERNAL: + spi_base = EXT_SPI; + break; + default: + return; + } + +#if 0 + /* Put a byte on MOSI, wait entire transfer, grab the byte from MOSI into buffer, repeat. */ + for (size_t i = 0; i < count; i++) { + uint8_t resp = spi_xfer(spi_base, data[i]); + data[i] = resp; + } +#else + CM_ATOMIC_CONTEXT(); + /* + * Start the waveform by putting first MOSI byte into TXDR + * from which it falls immediately into the shadow register + * (pipelined polling version with inter-byte-gaps removed, no IRQ, no DMA) + */ + spi_write(spi_base, data[0]); + /* + * Put the next MOSI byte into TXDR, + * wait for previous byte from MOSI to appear in RXDR and copy it into buffer, + * repeat N-2 times + */ + for (size_t i = 0; i < count - 1; i++) { + spi_send(spi_base, data[i + 1]); + data[i] = spi_read(spi_base); + } + /* Once the last MOSI byte comes out, grab the last MISO byte */ + data[count - 1] = spi_read(spi_base); +#endif +} + int platform_hwversion(void) { return 0; diff --git a/src/target/spi.c b/src/target/spi.c index 523fef9a2cd..9f54b3ae555 100644 --- a/src/target/spi.c +++ b/src/target/spi.c @@ -67,9 +67,13 @@ void bmp_spi_read(const spi_bus_e bus, const uint8_t device, const uint16_t comm bmp_spi_setup_xfer(bus, device, command, address); /* Now read back the data that elicited */ uint8_t *const data = (uint8_t *const)buffer; +#if 0 for (size_t i = 0; i < length; ++i) /* Do a write to read */ data[i] = platform_spi_xfer(bus, 0); +#else + platform_spi_xfer_block(bus, data, length); +#endif /* Deselect the Flash */ platform_spi_chip_select(device); } @@ -81,9 +85,13 @@ void bmp_spi_write(const spi_bus_e bus, const uint8_t device, const uint16_t com bmp_spi_setup_xfer(bus, device, command, address); /* Now write out back the data requested */ const uint8_t *const data = (const uint8_t *)buffer; +#if 0 for (size_t i = 0; i < length; ++i) /* Do a write to read */ platform_spi_xfer(bus, data[i]); +#else + platform_spi_xfer_block(bus, data, length); +#endif /* Deselect the Flash */ platform_spi_chip_select(device); }