From d6556428476787a41fef060dd2e3d7f1d890c9d0 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 28 Dec 2019 01:40:15 +0200 Subject: [PATCH] Add bootloader QSPI flash support. --- src/bootloader/src/main.c | 12 +++ src/bootloader/src/stm32fxxx_hal_msp.c | 79 ++++++++++++++ src/bootloader/src/usbd_cdc_interface.c | 124 +++++++++++++++++----- src/omv/boards/OPENMV4R/omv_boardconfig.h | 55 ++++++++++ src/sthal/h7/Makefile | 1 + 5 files changed, 244 insertions(+), 27 deletions(-) diff --git a/src/bootloader/src/main.c b/src/bootloader/src/main.c index f694e5394..63c351df7 100644 --- a/src/bootloader/src/main.c +++ b/src/bootloader/src/main.c @@ -12,6 +12,7 @@ #include "usbdev/usbd_cdc.h" #include "usbdev/usbd_desc.h" #include "omv_boardconfig.h" +#include "qspif.h" #define IDE_TIMEOUT (1000) #define CONFIG_TIMEOUT (2000) @@ -52,6 +53,12 @@ int main() HAL_Init(); + #if defined(OMV_QSPIF_LAYOUT) + if (qspif_init() != 0) { + __fatal_error(); + } + #endif + /* Init Device Library */ USBD_Init(&USBD_Device, &VCP_Desc, 0); @@ -95,6 +102,11 @@ int main() // Deinit USB USBD_DeInit(&USBD_Device); + #if defined(OMV_QSPIF_LAYOUT) + qspif_reset(); + qspif_deinit(); + #endif + // Disable IRQs __disable_irq(); __DSB(); __ISB(); diff --git a/src/bootloader/src/stm32fxxx_hal_msp.c b/src/bootloader/src/stm32fxxx_hal_msp.c index eb93ea0ee..82c0bd640 100644 --- a/src/bootloader/src/stm32fxxx_hal_msp.c +++ b/src/bootloader/src/stm32fxxx_hal_msp.c @@ -46,3 +46,82 @@ void HAL_MspInit() HAL_GPIO_Init(OMV_BOOTLDR_LED_PORT, &GPIO_InitStructure); HAL_GPIO_WritePin(OMV_BOOTLDR_LED_PORT, OMV_BOOTLDR_LED_PIN, GPIO_PIN_SET); } + +#if defined(OMV_QSPIF_LAYOUT) +void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi) +{ + GPIO_InitTypeDef gpio_init_structure; + + /*##-1- Enable peripherals and GPIO Clocks #################################*/ + /* Enable the QuadSPI memory interface clock */ + QSPIF_CLK_ENABLE(); + + /* Reset the QuadSPI memory interface */ + QSPIF_FORCE_RESET(); + QSPIF_RELEASE_RESET(); + + /* Enable GPIO clocks */ + QSPIF_CLK_GPIO_CLK_ENABLE(); + QSPIF_CS_GPIO_CLK_ENABLE(); + QSPIF_D0_GPIO_CLK_ENABLE(); + QSPIF_D1_GPIO_CLK_ENABLE(); + QSPIF_D2_GPIO_CLK_ENABLE(); + QSPIF_D3_GPIO_CLK_ENABLE(); + + /*##-2- Configure peripheral GPIO ##########################################*/ + /* QSPI CLK GPIO pin configuration */ + gpio_init_structure.Pin = QSPIF_CLK_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Alternate = QSPIF_CLK_ALT; + HAL_GPIO_Init(QSPIF_CLK_PORT, &gpio_init_structure); + + /* QSPI CS GPIO pin configuration */ + gpio_init_structure.Pin = QSPIF_CS_PIN; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Alternate = QSPIF_CS_ALT; + HAL_GPIO_Init(QSPIF_CS_PORT, &gpio_init_structure); + + /* QSPI D0 GPIO pin configuration */ + gpio_init_structure.Pin = QSPIF_D0_PIN; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Alternate = QSPIF_D0_ALT; + HAL_GPIO_Init(QSPIF_D0_PORT, &gpio_init_structure); + + /* QSPI D1 GPIO pin configuration */ + gpio_init_structure.Pin = QSPIF_D1_PIN; + gpio_init_structure.Alternate = QSPIF_D1_ALT; + HAL_GPIO_Init(QSPIF_D1_PORT, &gpio_init_structure); + + /* QSPI D2 GPIO pin configuration */ + gpio_init_structure.Pin = QSPIF_D2_PIN; + gpio_init_structure.Alternate = QSPIF_D2_ALT; + HAL_GPIO_Init(QSPIF_D2_PORT, &gpio_init_structure); + + /* QSPI D3 GPIO pin configuration */ + gpio_init_structure.Pin = QSPIF_D3_PIN; + gpio_init_structure.Alternate = QSPIF_D3_ALT; + HAL_GPIO_Init(QSPIF_D3_PORT, &gpio_init_structure); +} + +void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi) +{ + /*##-1- Disable peripherals and GPIO Clocks ################################*/ + /* De-Configure QSPI pins */ + HAL_GPIO_DeInit(QSPIF_CLK_PORT, QSPIF_CLK_PIN); + HAL_GPIO_DeInit(QSPIF_CS_PORT, QSPIF_CS_PIN); + HAL_GPIO_DeInit(QSPIF_D0_PORT, QSPIF_D0_PIN); + HAL_GPIO_DeInit(QSPIF_D1_PORT, QSPIF_D1_PIN); + HAL_GPIO_DeInit(QSPIF_D2_PORT, QSPIF_D2_PIN); + HAL_GPIO_DeInit(QSPIF_D3_PORT, QSPIF_D3_PIN); + + /*##-2- Reset peripherals ##################################################*/ + /* Reset the QuadSPI memory interface */ + QSPIF_FORCE_RESET(); + QSPIF_RELEASE_RESET(); + + /* Disable the QuadSPI memory interface clock */ + QSPIF_CLK_DISABLE(); +} +#endif // OMV_QSPIF_LAYOUT diff --git a/src/bootloader/src/usbd_cdc_interface.c b/src/bootloader/src/usbd_cdc_interface.c index ef69e03ac..fab24cfeb 100644 --- a/src/bootloader/src/usbd_cdc_interface.c +++ b/src/bootloader/src/usbd_cdc_interface.c @@ -2,6 +2,7 @@ #include "flash.h" #include "usbdev/usbd_cdc.h" #include "omv_boardconfig.h" +#include "qspif.h" #define APP_RX_DATA_SIZE (2048) #define APP_TX_DATA_SIZE (2048) @@ -29,7 +30,15 @@ static volatile uint8_t vcp_connected = 0; static volatile uint32_t flash_buf_idx=0; static volatile uint8_t flash_buf[FLASH_BUF_SIZE]; static const uint32_t flash_layout[3] = OMV_FLASH_LAYOUT; -static const uint32_t bootloader_version = 0xABCD0002; +#if defined(OMV_QSPIF_LAYOUT) +#define QSPIF_BUF_SIZE QSPIF_PAGE_SIZE +static volatile uint32_t qspif_buf_idx=0; +static volatile uint8_t qspif_buf[QSPIF_BUF_SIZE]; +static const uint32_t qspif_layout[3] = OMV_QSPIF_LAYOUT; +#else +static const uint32_t qspif_layout[3] = {0, 0, 0}; +#endif +static const uint32_t bootloader_version = 0xABCD0003; /* USB handler declaration */ extern USBD_HandleTypeDef USBD_Device; @@ -41,14 +50,18 @@ static int8_t CDC_Itf_Control(uint8_t cmd, uint8_t* pbuf, uint16_t length); static int8_t CDC_Itf_Receive(uint8_t* pbuf, uint32_t *Len); enum bootldr_cmd { - BOOTLDR_START = 0xABCD0001, - BOOTLDR_RESET = 0xABCD0002, - BOOTLDR_ERASE = 0xABCD0004, - BOOTLDR_WRITE = 0xABCD0008, - BOOTLDR_FLASH = 0xABCD0010, + BOOTLDR_START = 0xABCD0001, + BOOTLDR_RESET = 0xABCD0002, + BOOTLDR_FLASH_ERASE = 0xABCD0004, + BOOTLDR_FLASH_WRITE = 0xABCD0008, + BOOTLDR_FLASH_LAYOUT = 0xABCD0010, + BOOTLDR_QSPIF_ERASE = 0xABCD1004, + BOOTLDR_QSPIF_WRITE = 0xABCD1008, + BOOTLDR_QSPIF_LAYOUT = 0xABCD1010, + BOOTLDR_QSPIF_MEMTEST = 0xABCD1020, }; -USBD_CDC_ItfTypeDef USBD_CDC_fops = +USBD_CDC_ItfTypeDef USBD_CDC_fops = { CDC_Itf_Init, CDC_Itf_DeInit, @@ -85,7 +98,7 @@ static int8_t CDC_Itf_DeInit(void) /** * @brief CDC_Itf_Control * Manage the CDC class requests - * @param Cmd: Command code + * @param Cmd: Command code * @param Buf: Buffer containing command data (request parameters) * @param Len: Number of data to be sent (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL @@ -128,7 +141,7 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) pbuf[3] = (uint8_t)(LineCoding.bitrate >> 24); pbuf[4] = LineCoding.format; pbuf[5] = LineCoding.paritytype; - pbuf[6] = LineCoding.datatype; + pbuf[6] = LineCoding.datatype; break; case CDC_SET_CONTROL_LINE_STATE: @@ -137,7 +150,7 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) case CDC_SEND_BREAK: /* Add your code here */ - break; + break; default: break; @@ -187,7 +200,7 @@ void CDC_Tx(uint8_t *buf, uint32_t len) /** * @brief CDC_Itf_DataRx - * Data received over USB OUT endpoint are sent over CDC interface + * Data received over USB OUT endpoint are sent over CDC interface * through this function. * @param Buf: Buffer of data to be transmitted * @param Len: Number of data received (in bytes) @@ -196,38 +209,37 @@ void CDC_Tx(uint8_t *buf, uint32_t len) static int8_t CDC_Itf_Receive(uint8_t *Buf, uint32_t *Len) { static volatile uint32_t flash_offset; + #if defined(OMV_QSPIF_LAYOUT) + static volatile uint32_t qspif_offset=0; + #endif - uint32_t *cmd_buf = (uint32_t*) Buf; + uint32_t *cmd_buf = (uint32_t*) Buf; uint32_t cmd = *cmd_buf++; switch (cmd) { case BOOTLDR_START: flash_buf_idx = 0; + #if defined(OMV_QSPIF_LAYOUT) + qspif_buf_idx = 0; + #endif ide_connected = 1; flash_offset = MAIN_APP_ADDR; // Send back the bootloader version. CDC_Tx((uint8_t *) &bootloader_version, 4); break; - case BOOTLDR_FLASH: + + case BOOTLDR_FLASH_LAYOUT: // Return flash layout (bootloader v2) CDC_Tx((uint8_t*) flash_layout, 12); break; - case BOOTLDR_RESET: - ide_connected = 0; - if (flash_buf_idx) { - // Pad and flush the last packet - for (int i=flash_buf_idx; i