diff --git a/src/boot/common/dfu.c b/src/boot/common/dfu.c index 94a2fc728..e0bcc0909 100644 --- a/src/boot/common/dfu.c +++ b/src/boot/common/dfu.c @@ -33,6 +33,7 @@ #include #include #include "omv_bootconfig.h" +#include "flash.h" extern bool tud_dfu_detached; @@ -59,9 +60,9 @@ uint32_t tud_dfu_get_timeout_cb(uint8_t itf, uint8_t state) { } // Invoked when DFU_DNLOAD is received followed by DFU_GETSTATUS (state=DFU_DNBUSY). -void tud_dfu_download_cb(uint8_t itf, uint16_t block, uint8_t const *src, uint16_t size) { +void tud_dfu_download_cb(uint8_t itf, uint16_t block, uint8_t const *buf, uint16_t size) { const partition_t *p = &OMV_BOOT_PARTITIONS[itf]; - uint8_t *dst = (uint8_t *) (p->start + (block * CFG_TUD_DFU_XFER_BUFSIZE)); + uint32_t addr = p->start + (block * CFG_TUD_DFU_XFER_BUFSIZE); // Check if partition is writable. if (p->rdonly) { @@ -73,11 +74,11 @@ void tud_dfu_download_cb(uint8_t itf, uint16_t block, uint8_t const *src, uint16 port_mpu_protect(p, false); } - if ((uint32_t) dst + size > p->limit) { + if (addr + size > p->limit) { return tud_dfu_finish_flashing(DFU_STATUS_ERR_ADDRESS); } - if (port_flash_write(p->type, (uint32_t) dst, src, size) == 0) { + if (flash_write(p->type, addr, buf, size) == 0) { tud_dfu_finish_flashing(DFU_STATUS_OK); } else { tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE); @@ -92,23 +93,22 @@ void tud_dfu_manifest_cb(uint8_t itf) { } // Invoked when DFU_UPLOAD request is received. -uint16_t tud_dfu_upload_cb(uint8_t itf, uint16_t block, uint8_t *dst, uint16_t size) { +uint16_t tud_dfu_upload_cb(uint8_t itf, uint16_t block, uint8_t *buf, uint16_t size) { const partition_t *p = &OMV_BOOT_PARTITIONS[itf]; - uint8_t *src = (uint8_t *) (p->start + (block * CFG_TUD_DFU_XFER_BUFSIZE)); + uint32_t addr = p->start + (block * CFG_TUD_DFU_XFER_BUFSIZE); - if ((uint32_t) src + size > p->limit) { + if (addr + size > p->limit) { // Respond with a short frame to indicate EOF to the host. size = 4; - memset(dst, 0, size); - } else if (port_flash_read(p->type, (uint32_t) src, dst, size) != 0) { + memset(buf, 0, size); + tud_dfu_finish_flashing(DFU_STATUS_OK); + } else if (flash_read(p->type, addr, buf, size) != 0) { size = 0; + tud_dfu_finish_flashing(DFU_STATUS_ERR_FILE); + } else { + tud_dfu_finish_flashing(DFU_STATUS_OK); } - if (size) { - tud_dfu_finish_flashing(DFU_STATUS_OK); - } else { - tud_dfu_finish_flashing(DFU_STATUS_ERR_FILE); - } tud_dfu_detached = false; return size; } diff --git a/src/boot/ports/stm32/stm32_flash.h b/src/boot/common/flash.h similarity index 68% rename from src/boot/ports/stm32/stm32_flash.h rename to src/boot/common/flash.h index 1ebd1df83..a3d356bee 100644 --- a/src/boot/ports/stm32/stm32_flash.h +++ b/src/boot/common/flash.h @@ -28,13 +28,42 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * STM32 Flash driver. + * Bootloader flash interface. */ -#ifndef __STM32_FLASH_H__ -#define __STM32_FLASH_H__ +#ifndef __BOOT_FLASH_H__ +#define __BOOT_FLASH_H__ int axi_flash_read(uint32_t addr, uint8_t *buf, size_t size); int axi_flash_write(uint32_t addr, const uint8_t *buf, size_t size); + +int spi_flash_deinit(); int spi_flash_read(uint32_t addr, uint8_t *buf, uint32_t size); int spi_flash_write(uint32_t addr, const uint8_t *buf, uint32_t size); -int spi_flash_deinit(); -#endif //__STM32_FLASH_H__ + +static inline int flash_read(uint32_t ptype, uint32_t addr, uint8_t *buf, uint32_t size) { + #if OMV_BOOT_AXI_FLASH_ENABLE + if (ptype == PTYPE_AXI_FLASH) { + return axi_flash_read(addr, buf, size); + } + #endif + #if OMV_BOOT_SPI_FLASH_ENABLE + if (ptype == PTYPE_SPI_FLASH) { + return spi_flash_read(addr, buf, size); + } + #endif + return -1; +} + +static inline int flash_write(uint32_t ptype, uint32_t addr, const uint8_t *buf, uint32_t size) { + #if OMV_BOOT_AXI_FLASH_ENABLE + if (ptype == PTYPE_AXI_FLASH) { + return axi_flash_write(addr, buf, size); + } + #endif + #if OMV_BOOT_SPI_FLASH_ENABLE + if (ptype == PTYPE_SPI_FLASH) { + return spi_flash_write(addr, buf, size); + } + #endif + return -1; +} +#endif //__BOOT_FLASH_H__ diff --git a/src/boot/ports/stm32/stm32_flash.c b/src/boot/ports/stm32/stm32_flash.c index fded7cfc9..894843394 100644 --- a/src/boot/ports/stm32/stm32_flash.c +++ b/src/boot/ports/stm32/stm32_flash.c @@ -35,7 +35,6 @@ #include "omv_boardconfig.h" #include "omv_bootconfig.h" -#include "stm32_flash.h" #if OMV_BOOT_AXI_FLASH_ENABLE diff --git a/src/boot/ports/stm32/stm32_port.c b/src/boot/ports/stm32/stm32_port.c index 75f2c3496..f70f43965 100644 --- a/src/boot/ports/stm32/stm32_port.c +++ b/src/boot/ports/stm32/stm32_port.c @@ -36,7 +36,7 @@ #include STM32_HAL_H #include "omv_boardconfig.h" #include "omv_bootconfig.h" -#include "stm32_flash.h" +#include "flash.h" #ifdef USE_USB_FS #define USB_IRQ_Handler OTG_FS_IRQHandler @@ -226,34 +226,6 @@ void port_led_blink(uint32_t interval_ms) { start_ms += interval_ms; } -int port_flash_read(uint32_t ptype, uint32_t addr, uint8_t *buf, uint32_t size) { - #if OMV_BOOT_AXI_FLASH_ENABLE - if (ptype == PTYPE_AXI_FLASH) { - return axi_flash_read(addr, buf, size); - } - #endif - #if OMV_BOOT_SPI_FLASH_ENABLE - if (ptype == PTYPE_SPI_FLASH) { - return spi_flash_read(addr, buf, size); - } - #endif - return -1; -} - -int port_flash_write(uint32_t ptype, uint32_t addr, const uint8_t *buf, uint32_t size) { - #if OMV_BOOT_AXI_FLASH_ENABLE - if (ptype == PTYPE_AXI_FLASH) { - return axi_flash_write(addr, buf, size); - } - #endif - #if OMV_BOOT_SPI_FLASH_ENABLE - if (ptype == PTYPE_SPI_FLASH) { - return spi_flash_write(addr, buf, size); - } - #endif - return -1; -} - void __attribute__((noreturn)) __fatal_error() { while (1) { port_led_blink(50); diff --git a/src/boot/ports/stm32/stm32_qspi.c b/src/boot/ports/stm32/stm32_qspi.c index f245a96ae..fd7351b30 100644 --- a/src/boot/ports/stm32/stm32_qspi.c +++ b/src/boot/ports/stm32/stm32_qspi.c @@ -34,7 +34,6 @@ #include STM32_HAL_H #include "omv_boardconfig.h" #include "omv_bootconfig.h" -#include "stm32_flash.h" #if OMV_BOOT_QSPI_FLASH_SIZE @@ -291,50 +290,6 @@ static int qspi_flash_erase_block(uint32_t addr) { return 0; } -int __attribute__((optimize("O0"))) qspi_flash_memory_test() { - uint8_t buf[QSPI_PAGE_SIZE]; - uint8_t pat[QSPI_PAGE_SIZE]; - - uint32_t n_pages = OMV_BOOT_QSPI_FLASH_SIZE / QSPI_PAGE_SIZE; - uint32_t n_blocks = OMV_BOOT_QSPI_FLASH_SIZE / QSPI_BLOCK_SIZE; - - if (qspi.Instance == NULL || qspi_flash_init() != 0) { - return -1; - } - - for (int i = 0; i < QSPI_PAGE_SIZE; i++) { - pat[i] = ((i % 2) == 0) ? 0xaa : 0x55; - } - - for (uint32_t i = 0, addr = 0; i < n_blocks; i++, addr += QSPI_BLOCK_SIZE) { - if (qspi_flash_erase_block(addr) != 0) { - return -2; - } - } - - for (uint32_t i = 0, addr = 0; i < n_pages; i++, addr += QSPI_PAGE_SIZE) { - if (spi_flash_write(addr, pat, QSPI_PAGE_SIZE) != 0) { - return -3; - } - } - - for (uint32_t i = 0, addr = 0; i < n_pages; i++, addr += QSPI_PAGE_SIZE) { - memset(buf, 0, QSPI_PAGE_SIZE); - if (spi_flash_read(addr, buf, QSPI_PAGE_SIZE) != 0) { - return -4; - } - if (memcmp(buf, pat, QSPI_PAGE_SIZE) != 0) { - return -5; - } - } - - if (qspi_flash_erase_chip() != 0) { - return -6; - } - - return 0; -} - static int qspi_flash_read_page(uint32_t addr, uint8_t *buf, uint32_t size) { QSPI_CommandTypeDef command = { .InstructionMode = QSPI_INSTRUCTION_1_LINE, @@ -415,6 +370,66 @@ static int qspi_flash_write_page(uint32_t addr, const uint8_t *buf, uint32_t siz return 0; } +int __attribute__((optimize("O0"))) qspi_flash_memory_test() { + uint8_t buf[QSPI_PAGE_SIZE]; + uint8_t pat[QSPI_PAGE_SIZE]; + + uint32_t n_pages = OMV_BOOT_QSPI_FLASH_SIZE / QSPI_PAGE_SIZE; + uint32_t n_blocks = OMV_BOOT_QSPI_FLASH_SIZE / QSPI_BLOCK_SIZE; + + if (qspi.Instance == NULL || qspi_flash_init() != 0) { + return -1; + } + + for (int i = 0; i < QSPI_PAGE_SIZE; i++) { + pat[i] = ((i % 2) == 0) ? 0xaa : 0x55; + } + + for (uint32_t i = 0, addr = 0; i < n_blocks; i++, addr += QSPI_BLOCK_SIZE) { + if (qspi_flash_erase_block(addr) != 0) { + return -2; + } + } + + for (uint32_t i = 0, addr = 0; i < n_pages; i++, addr += QSPI_PAGE_SIZE) { + if (qspi_flash_write_page(addr, pat, QSPI_PAGE_SIZE) != 0) { + return -3; + } + } + + for (uint32_t i = 0, addr = 0; i < n_pages; i++, addr += QSPI_PAGE_SIZE) { + memset(buf, 0, QSPI_PAGE_SIZE); + if (qspi_flash_read_page(addr, buf, QSPI_PAGE_SIZE) != 0) { + return -4; + } + if (memcmp(buf, pat, QSPI_PAGE_SIZE) != 0) { + return -5; + } + } + + if (qspi_flash_erase_chip() != 0) { + return -6; + } + + return 0; +} + +int spi_flash_deinit() { + if (qspi.Instance != NULL) { + HAL_QSPI_DeInit(&qspi); + qspi.Instance = NULL; + } + + // Reset QSPI. + __HAL_RCC_QSPI_FORCE_RESET(); + __HAL_RCC_QSPI_RELEASE_RESET(); + + // Disable QSPI clock. + __HAL_RCC_QSPI_CLK_DISABLE(); + memset(&qspi, 0, sizeof(QSPI_HandleTypeDef)); + return 0; +} + int spi_flash_read(uint32_t addr, uint8_t *buf, uint32_t size) { for (size_t i = 0; i < size / QSPI_PAGE_SIZE; i++) { if (qspi_flash_read_page(addr, buf, QSPI_PAGE_SIZE) != 0) { @@ -455,21 +470,4 @@ int spi_flash_write(uint32_t addr, const uint8_t *buf, uint32_t size) { } return 0; } - - -int spi_flash_deinit() { - if (qspi.Instance != NULL) { - HAL_QSPI_DeInit(&qspi); - qspi.Instance = NULL; - } - - // Reset QSPI. - __HAL_RCC_QSPI_FORCE_RESET(); - __HAL_RCC_QSPI_RELEASE_RESET(); - - // Disable QSPI clock. - __HAL_RCC_QSPI_CLK_DISABLE(); - memset(&qspi, 0, sizeof(QSPI_HandleTypeDef)); - return 0; -} #endif // OMV_BOOT_QSPI_FLASH_SIZE