aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src')
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/dfu_mal.c253
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/flash_if.c171
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/fsmc_nor.c427
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/spi_if.c110
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f30x.c382
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f37x.c380
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_desc.c489
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_prop.c745
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_pwr.c318
9 files changed, 3275 insertions, 0 deletions
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/dfu_mal.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/dfu_mal.c
new file mode 100644
index 0000000..b0e8366
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/dfu_mal.c
@@ -0,0 +1,253 @@
+/**
+ ******************************************************************************
+ * @file dfu_mal.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief Generic media access Layer
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "hw_config.h"
+#include "dfu_mal.h"
+#include "usb_lib.h"
+#include "usb_type.h"
+#include "usb_desc.h"
+#include "flash_if.h"
+
+#if !defined(STM32L1XX_MD) && !defined(STM32L1XX_HD) && !defined(STM32L1XX_MD_PLUS)&& !defined (USE_STM32373C_EVAL) && !defined (USE_STM32303C_EVAL)
+ #include "spi_if.h"
+
+ #include "nor_if.h"
+ #include "fsmc_nor.h"
+#endif /* STM32L1XX_MD && USE_STM32373C_EVAL*/
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint16_t (*pMAL_Init) (void);
+uint16_t (*pMAL_Erase) (uint32_t SectorAddress);
+uint16_t (*pMAL_Write) (uint32_t SectorAddress, uint32_t DataLength);
+uint8_t *(*pMAL_Read) (uint32_t SectorAddress, uint32_t DataLength);
+uint8_t MAL_Buffer[wTransferSize]; /* RAM Buffer for Downloaded Data */
+
+#if !defined(STM32L1XX_MD) && !defined(STM32L1XX_HD) && !defined(STM32L1XX_MD_PLUS)&& !defined (USE_STM32373C_EVAL) && !defined (USE_STM32303C_EVAL)
+ NOR_IDTypeDef NOR_ID;
+#endif /* STM32L1XX_XD */
+
+extern ONE_DESCRIPTOR DFU_String_Descriptor[7];
+
+/* This table holds the Typical Sector Erase and 1024 Bytes Write timings.
+ These timings will be returned to the host when it checks the device
+ status during a write or erase operation to know how much time the host
+ should wait before issuing the next get status request.
+ These defines are set in usb_conf.h file.
+ The values of this table should be extracted from relative memories
+ datasheet (Typical or Maximum timming value for Sector Erase and for
+ 1024 bytes Write). All timings are expressed in millisecond unit (ms).
+ Note that "Sector" refers here to the memory unit used for Erase/Write
+ operations. It could be a sector, a page, a block, a word ...
+ If the erase operation is not supported, it is advised to set the erase
+ timing to 1 (which means 1ms: one USB frame). */
+static const uint16_t TimingTable[5][2] =
+ { /* Sector Erase time, Sector Program time*/
+ { SPI_FLASH_SECTOR_ERASE_TIME, SPI_FLASH_SECTOR_WRITE_TIME }, /* SPI Flash */
+ { M29W128F_SECTOR_ERASE_TIME, M29W128F_SECTOR_WRITE_TIME }, /* NOR Flash M29W128F */
+ { INTERN_FLASH_SECTOR_ERASE_TIME, INTERN_FLASH_SECTOR_WRITE_TIME }, /* Internal Flash */
+ { M29W128G_SECTOR_ERASE_TIME, M29W128G_SECTOR_WRITE_TIME }, /* NOR Flash M29W128G */
+ { S29GL128_SECTOR_ERASE_TIME, S29GL128_SECTOR_WRITE_TIME } /* NOR Flash S29GL128 */
+ };
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : MAL_Init
+* Description : Initializes the Media on the STM32
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t MAL_Init(void)
+{
+
+ FLASH_If_Init(); /* Internal Flash */
+
+#if defined(USE_STM3210B_EVAL) || defined(USE_STM3210E_EVAL)
+ SPI_If_Init(); /* SPI Flash */
+#endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */
+
+#ifdef USE_STM3210E_EVAL
+ NOR_If_Init(); /* NOR Flash */
+ FSMC_NOR_ReadID(&NOR_ID);
+
+ FSMC_NOR_ReturnToReadMode();
+
+ /* select the alternate descriptor following NOR ID */
+ if ((NOR_ID.Manufacturer_Code == 0x01)&&(NOR_ID.Device_Code2 == NOR_S29GL128))
+ {
+ DFU_String_Descriptor[6].Descriptor = DFU_StringInterface2_3;
+ }
+
+ /* select the alternate descriptor following NOR ID */
+ if ((NOR_ID.Manufacturer_Code == 0x20)&&(NOR_ID.Device_Code2 == NOR_M29W128G))
+ {
+ DFU_String_Descriptor[6].Descriptor = DFU_StringInterface2_2;
+ }
+#endif /* USE_STM3210E_EVAL */
+
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : MAL_Erase
+* Description : Erase sector
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t MAL_Erase(uint32_t SectorAddress)
+{
+
+ switch (SectorAddress & MAL_MASK)
+ {
+ case INTERNAL_FLASH_BASE:
+ pMAL_Erase = FLASH_If_Erase;
+ break;
+
+#if defined(USE_STM3210B_EVAL) || defined(USE_STM3210E_EVAL)
+ case SPI_FLASH_BASE:
+ pMAL_Erase = SPI_If_Erase;
+ break;
+#endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */
+
+#ifdef USE_STM3210E_EVAL
+ case NOR_FLASH_BASE:
+ pMAL_Erase = NOR_If_Erase;
+ break;
+#endif /* USE_STM3210E_EVAL */
+
+ default:
+ return MAL_FAIL;
+ }
+ return pMAL_Erase(SectorAddress);
+}
+
+/*******************************************************************************
+* Function Name : MAL_Write
+* Description : Write sectors
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength)
+{
+
+ switch (SectorAddress & MAL_MASK)
+ {
+ case INTERNAL_FLASH_BASE:
+ pMAL_Write = FLASH_If_Write;
+ break;
+
+#if defined(USE_STM3210B_EVAL) || defined(USE_STM3210E_EVAL)
+ case SPI_FLASH_BASE:
+ pMAL_Write = SPI_If_Write;
+ break;
+#endif /* USE_STM3210B_EVAL || USE_STM3210E_EVAL */
+
+#ifdef USE_STM3210E_EVAL
+ case NOR_FLASH_BASE:
+ pMAL_Write = NOR_If_Write;
+ break;
+#endif /* USE_STM3210E_EVAL */
+ default:
+ return MAL_FAIL;
+ }
+ return pMAL_Write(SectorAddress, DataLength);
+}
+
+/*******************************************************************************
+* Function Name : MAL_Read
+* Description : Read sectors
+* Input : None
+* Output : None
+* Return : Buffer pointer
+*******************************************************************************/
+uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength)
+{
+
+ switch (SectorAddress & MAL_MASK)
+ {
+ case INTERNAL_FLASH_BASE:
+ pMAL_Read = FLASH_If_Read;
+ break;
+
+#if defined(USE_STM3210B_EVAL) || defined(USE_STM3210E_EVAL)
+ case SPI_FLASH_BASE:
+ pMAL_Read = SPI_If_Read;
+ break;
+#endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */
+
+#ifdef USE_STM3210E_EVAL
+ case NOR_FLASH_BASE:
+ pMAL_Read = NOR_If_Read;
+ break;
+#endif /* USE_STM3210E_EVAL */
+
+ default:
+ return 0;
+ }
+ return pMAL_Read (SectorAddress, DataLength);
+}
+
+/*******************************************************************************
+* Function Name : MAL_GetStatus
+* Description : Get status
+* Input : None
+* Output : None
+* Return : Buffer pointer
+*******************************************************************************/
+uint16_t MAL_GetStatus(uint32_t SectorAddress , uint8_t Cmd, uint8_t *buffer)
+{
+ uint8_t x = (SectorAddress >> 26) & 0x03 ; /* 0x000000000 --> 0 */
+ /* 0x640000000 --> 1 */
+ /* 0x080000000 --> 2 */
+
+ uint8_t y = Cmd & 0x01;
+
+#if defined(USE_STM3210E_EVAL)
+ if ((x == 1) && (NOR_ID.Device_Code2 == NOR_M29W128G)&& (NOR_ID.Manufacturer_Code == 0x20))
+ {
+ x = 3 ;
+ }
+ else if((x == 1) && (NOR_ID.Device_Code2 == NOR_S29GL128) && (NOR_ID.Manufacturer_Code == 0x01))
+ {
+ x = 4 ;
+ }
+#endif /* USE_STM3210E_EVAL */
+
+ SET_POLLING_TIMING(TimingTable[x][y]); /* x: Erase/Write Timing */
+ /* y: Media */
+ return MAL_OK;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/flash_if.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/flash_if.c
new file mode 100644
index 0000000..e6caf41
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/flash_if.c
@@ -0,0 +1,171 @@
+/**
+ ******************************************************************************
+ * @file flash_if.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief specific media access Layer for internal flash
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "flash_if.h"
+#include "dfu_mal.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+#if defined(STM32L1XX_MD) || defined(STM32L1XX_HD)|| defined(STM32L1XX_MD_PLUS)
+ uint32_t tHalfPage1[128/4];
+ uint32_t tHalfPage2[128/4];
+#endif /* STM32L1XX_XD */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : FLASH_If_Init
+* Description : Initializes the Media on the STM32
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t FLASH_If_Init(void)
+{
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : FLASH_If_Erase
+* Description : Erase sector
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t FLASH_If_Erase(uint32_t SectorAddress)
+{
+#if defined(STM32L1XX_MD) || defined(STM32L1XX_HD)|| defined(STM32L1XX_MD_PLUS)
+ FLASH_ClearFlag(FLASH_FLAG_PGAERR | FLASH_FLAG_OPTVERR);
+ FLASH_ErasePage(SectorAddress);
+#else
+ FLASH_ErasePage(SectorAddress);
+#endif /* STM32L1XX_XD */
+
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : FLASH_If_Write
+* Description : Write sectors
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t FLASH_If_Write(uint32_t SectorAddress, uint32_t DataLength)
+{
+ uint32_t idx = 0;
+#if defined(STM32L1XX_MD) || defined(STM32L1XX_HD)|| defined(STM32L1XX_MD_PLUS)
+ __IO uint32_t* malPointer = (uint32_t *)MAL_Buffer;
+ __IO uint32_t* memPointer = (uint32_t *)SectorAddress;
+ __IO uint32_t memBuffer[32]; /* Temporary buffer holding data that will be written in a half-page space */
+ __IO uint32_t* mempBuffer = memBuffer;
+ __IO uint32_t* tmp;
+#endif /* STM32L1XX_XD */
+
+ if (DataLength & 0x3) /* Not an aligned data */
+ {
+ for (idx = DataLength; idx < ((DataLength & 0xFFFC) + 4); idx++)
+ {
+ MAL_Buffer[idx] = 0xFF;
+ }
+ }
+
+#if defined(STM32L1XX_MD) || defined(STM32L1XX_HD)|| defined(STM32L1XX_MD_PLUS)
+ /* Reinitialize the intermediate buffer pointer */
+ mempBuffer = memBuffer;
+
+ /* If the address is not aligned to half-page fill the first location with existing data */
+ if (((uint32_t)memPointer & 0x7F) != 0)
+ {
+ /* get the aligned address */
+ tmp = (uint32_t *)((uint32_t)memPointer & 0xFFFFFF80);
+
+ /* Read the first part from the memory */
+ while (tmp < memPointer)
+ {
+ *(uint32_t *)(mempBuffer++) = *(uint32_t *)(tmp++);
+ }
+ }
+
+ while (malPointer < (uint32_t*)(MAL_Buffer + DataLength))
+ {
+ /* Fill with the received buffer */
+ while (mempBuffer < (memBuffer + 32))
+ {
+ /* If there are still data available in the received buffer */
+ if (malPointer < ((uint32_t *)MAL_Buffer + DataLength))
+ {
+ *(uint32_t *)(mempBuffer++) = *(uint32_t *)(malPointer++);
+ }
+ else /* no more data available in the received buffer: fill remaining with dummy 0 */
+ {
+ *(uint32_t *)(mempBuffer++) = 0;
+ }
+ }
+
+ /* Write the buffer to the memory*/
+ FLASH_ProgramHalfPage(((uint32_t)memPointer & 0xFFFFFF80), (uint32_t *)(memBuffer));
+
+ /* Increment the memory pointer */
+ memPointer = (uint32_t *)(((uint32_t)memPointer & 0xFFFFFF80) + (32*4));
+
+ /* Reinitialize the intermediate buffer pointer */
+ mempBuffer = memBuffer;
+ }
+
+#else
+
+ /* Data received are Word multiple */
+ for (idx = 0; idx < DataLength; idx = idx + 4)
+ {
+ FLASH_ProgramWord(SectorAddress, *(uint32_t *)(MAL_Buffer + idx));
+ SectorAddress += 4;
+ }
+#endif /* STM32L1XX_XD */
+
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : FLASH_If_Read
+* Description : Read sectors
+* Input : None
+* Output : None
+* Return : buffer address pointer
+*******************************************************************************/
+uint8_t *FLASH_If_Read (uint32_t SectorAddress, uint32_t DataLength)
+{
+ return (uint8_t*)(SectorAddress);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/fsmc_nor.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/fsmc_nor.c
new file mode 100644
index 0000000..cdcfcdf
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/fsmc_nor.c
@@ -0,0 +1,427 @@
+/**
+ ******************************************************************************
+ * @file fsmc_nor.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief This file provides a set of functions needed to drive the M29W128FL,
+ * M29W128GL and S29GL128P NOR memories mounted on STM3210E-EVAL board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "fsmc_nor.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define Bank1_NOR2_ADDR ((uint32_t)0x64000000)
+
+/* Delay definition */
+#define BlockErase_Timeout ((uint32_t)0x00A00000)
+#define ChipErase_Timeout ((uint32_t)0x30000000)
+#define Program_Timeout ((uint32_t)0x00001400)
+
+/* Private macro -------------------------------------------------------------*/
+#define ADDR_SHIFT(A) (Bank1_NOR2_ADDR + (2 * (A)))
+#define NOR_WRITE(Address, Data) (*(__IO uint16_t *)(Address) = (Data))
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name : FSMC_NOR_Init
+* Description : Configures the FSMC and GPIOs to interface with the NOR memory.
+* This function must be called before any write/read operation
+* on the NOR.
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+void FSMC_NOR_Init(void)
+{
+ FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
+ FSMC_NORSRAMTimingInitTypeDef p;
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
+ RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
+
+ /*-- GPIO Configuration ------------------------------------------------------*/
+ /* NOR Data lines configuration */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
+ GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
+ GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
+ GPIO_Pin_14 | GPIO_Pin_15;
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+ /* NOR Address lines configuration */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
+ GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
+ GPIO_Pin_14 | GPIO_Pin_15;
+ GPIO_Init(GPIOF, &GPIO_InitStructure);
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |
+ GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
+ GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+ /* NOE and NWE configuration */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ /* NE2 configuration */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+ GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+ /*-- FSMC Configuration ----------------------------------------------------*/
+ p.FSMC_AddressSetupTime = 0x02;
+ p.FSMC_AddressHoldTime = 0x00;
+ p.FSMC_DataSetupTime = 0x05;
+ p.FSMC_BusTurnAroundDuration = 0x00;
+ p.FSMC_CLKDivision = 0x00;
+ p.FSMC_DataLatency = 0x00;
+ p.FSMC_AccessMode = FSMC_AccessMode_B;
+
+ FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
+ FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
+ FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
+ FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+ FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+ FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+ FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+
+ FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
+
+ /* Enable FSMC Bank1_NOR Bank */
+ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
+}
+
+/******************************************************************************
+* Function Name : FSMC_NOR_ReadID
+* Description : Reads NOR memory's Manufacturer and Device Code.
+* Input : - NOR_ID: pointer to a NOR_IDTypeDef structure which will hold
+* the Manufacturer and Device Code.
+* Output : None
+* Return : None
+*******************************************************************************/
+void FSMC_NOR_ReadID(NOR_IDTypeDef* NOR_ID)
+{
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x0090);
+
+ NOR_ID->Manufacturer_Code = *(__IO uint16_t *) ADDR_SHIFT(0x0000);
+ NOR_ID->Device_Code1 = *(__IO uint16_t *) ADDR_SHIFT(0x0001);
+ NOR_ID->Device_Code2 = *(__IO uint16_t *) ADDR_SHIFT(0x000E);
+ NOR_ID->Device_Code3 = *(__IO uint16_t *) ADDR_SHIFT(0x000F);
+}
+
+/*******************************************************************************
+* Function Name : FSMC_NOR_EraseBlock
+* Description : Erases the specified Nor memory block.
+* Input : - BlockAddr: address of the block to erase.
+* Output : None
+* Return : NOR_Status:The returned value can be: NOR_SUCCESS, NOR_ERROR
+* or NOR_TIMEOUT
+*******************************************************************************/
+NOR_Status FSMC_NOR_EraseBlock(uint32_t BlockAddr)
+{
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE((Bank1_NOR2_ADDR + BlockAddr), 0x30);
+
+ return (FSMC_NOR_GetStatus(BlockErase_Timeout));
+}
+
+/*******************************************************************************
+* Function Name : FSMC_NOR_EraseChip
+* Description : Erases the entire chip.
+* Input : None
+* Output : None
+* Return : NOR_Status:The returned value can be: NOR_SUCCESS, NOR_ERROR
+* or NOR_TIMEOUT
+*******************************************************************************/
+NOR_Status FSMC_NOR_EraseChip(void)
+{
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x0010);
+
+ return (FSMC_NOR_GetStatus(ChipErase_Timeout));
+}
+
+/******************************************************************************
+* Function Name : FSMC_NOR_WriteHalfWord
+* Description : Writes a half-word to the NOR memory.
+* Input : - WriteAddr : NOR memory internal address to write to.
+* - Data : Data to write.
+* Output : None
+* Return : NOR_Status:The returned value can be: NOR_SUCCESS, NOR_ERROR
+* or NOR_TIMEOUT
+*******************************************************************************/
+NOR_Status FSMC_NOR_WriteHalfWord(uint32_t WriteAddr, uint16_t Data)
+{
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);
+ NOR_WRITE((Bank1_NOR2_ADDR + WriteAddr), Data);
+
+ return (FSMC_NOR_GetStatus(Program_Timeout));
+}
+
+/*******************************************************************************
+* Function Name : FSMC_NOR_WriteBuffer
+* Description : Writes a half-word buffer to the FSMC NOR memory.
+* Input : - pBuffer : pointer to buffer.
+* - WriteAddr : NOR memory internal address from which the data
+* will be written.
+* - NumHalfwordToWrite : number of Half words to write.
+* Output : None
+* Return : NOR_Status:The returned value can be: NOR_SUCCESS, NOR_ERROR
+* or NOR_TIMEOUT
+*******************************************************************************/
+NOR_Status FSMC_NOR_WriteBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)
+{
+ NOR_Status status = NOR_ONGOING;
+
+ do
+ {
+ /* Transfer data to the memory */
+ status = FSMC_NOR_WriteHalfWord(WriteAddr, *pBuffer++);
+ WriteAddr = WriteAddr + 2;
+ NumHalfwordToWrite--;
+ }
+ while((status == NOR_SUCCESS) && (NumHalfwordToWrite != 0));
+
+ return (status);
+}
+
+/*******************************************************************************
+* Function Name : FSMC_NOR_ProgramBuffer
+* Description : Writes a half-word buffer to the FSMC NOR memory. This function
+* must be used only with S29GL128P NOR memory.
+* Input : - pBuffer : pointer to buffer.
+* - WriteAddr: NOR memory internal address from which the data
+* will be written.
+* - NumHalfwordToWrite: number of Half words to write.
+* The maximum allowed value is 32 Half words (64 bytes).
+* Output : None
+* Return : NOR_Status:The returned value can be: NOR_SUCCESS, NOR_ERROR
+* or NOR_TIMEOUT
+*******************************************************************************/
+NOR_Status FSMC_NOR_ProgramBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)
+{
+ uint32_t lastloadedaddress = 0x00;
+ uint32_t currentaddress = 0x00;
+ uint32_t endaddress = 0x00;
+
+ /* Initialize variables */
+ currentaddress = WriteAddr;
+ endaddress = WriteAddr + NumHalfwordToWrite - 1;
+ lastloadedaddress = WriteAddr;
+
+ /* Issue unlock command sequence */
+ NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
+
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+
+ /* Write Write Buffer Load Command */
+ NOR_WRITE(ADDR_SHIFT(WriteAddr), 0x0025);
+ NOR_WRITE(ADDR_SHIFT(WriteAddr), (NumHalfwordToWrite - 1));
+
+ /* Load Data into NOR Buffer */
+ while(currentaddress <= endaddress)
+ {
+ /* Store last loaded address & data value (for polling) */
+ lastloadedaddress = currentaddress;
+
+ NOR_WRITE(ADDR_SHIFT(currentaddress), *pBuffer++);
+ currentaddress += 1;
+ }
+
+ NOR_WRITE(ADDR_SHIFT(lastloadedaddress), 0x29);
+
+ return(FSMC_NOR_GetStatus(Program_Timeout));
+}
+
+/******************************************************************************
+* Function Name : FSMC_NOR_ReadHalfWord
+* Description : Reads a half-word from the NOR memory.
+* Input : - ReadAddr : NOR memory internal address to read from.
+* Output : None
+* Return : Half-word read from the NOR memory
+*******************************************************************************/
+uint16_t FSMC_NOR_ReadHalfWord(uint32_t ReadAddr)
+{
+ NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);
+ NOR_WRITE((Bank1_NOR2_ADDR + ReadAddr), 0x00F0 );
+
+ return (*(__IO uint16_t *)((Bank1_NOR2_ADDR + ReadAddr)));
+}
+
+/*******************************************************************************
+* Function Name : FSMC_NOR_ReadBuffer
+* Description : Reads a block of data from the FSMC NOR memory.
+* Input : - pBuffer : pointer to the buffer that receives the data read
+* from the NOR memory.
+* - ReadAddr : NOR memory internal address to read from.
+* - NumHalfwordToRead : number of Half word to read.
+* Output : None
+* Return : None
+*******************************************************************************/
+void FSMC_NOR_ReadBuffer(uint16_t* pBuffer, uint32_t ReadAddr, uint32_t NumHalfwordToRead)
+{
+ NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
+ NOR_WRITE((Bank1_NOR2_ADDR + ReadAddr), 0x00F0);
+
+ for(; NumHalfwordToRead != 0x00; NumHalfwordToRead--) /* while there is data to read */
+ {
+ /* Read a Halfword from the NOR */
+ *pBuffer++ = *(__IO uint16_t *)((Bank1_NOR2_ADDR + ReadAddr));
+ ReadAddr = ReadAddr + 2;
+ }
+}
+
+/******************************************************************************
+* Function Name : FSMC_NOR_ReturnToReadMode
+* Description : Returns the NOR memory to Read mode.
+* Input : None
+* Output : None
+* Return : NOR_SUCCESS
+*******************************************************************************/
+NOR_Status FSMC_NOR_ReturnToReadMode(void)
+{
+ NOR_WRITE(Bank1_NOR2_ADDR, 0x00F0);
+
+ return (NOR_SUCCESS);
+}
+
+/******************************************************************************
+* Function Name : FSMC_NOR_Reset
+* Description : Returns the NOR memory to Read mode and resets the errors in
+* the NOR memory Status Register.
+* Input : None
+* Output : None
+* Return : NOR_SUCCESS
+*******************************************************************************/
+NOR_Status FSMC_NOR_Reset(void)
+{
+ NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
+ NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);
+ NOR_WRITE(Bank1_NOR2_ADDR, 0x00F0);
+
+ return (NOR_SUCCESS);
+}
+
+/******************************************************************************
+* Function Name : FSMC_NOR_GetStatus
+* Description : Returns the NOR operation status.
+* Input : - Timeout: NOR programming Timeout
+* Output : None
+* Return : NOR_Status:The returned value can be: NOR_SUCCESS, NOR_ERROR
+* or NOR_TIMEOUT
+*******************************************************************************/
+NOR_Status FSMC_NOR_GetStatus(uint32_t Timeout)
+{
+ uint16_t val1 = 0x00, val2 = 0x00;
+ NOR_Status status = NOR_ONGOING;
+ uint32_t timeout = Timeout;
+
+ /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
+ while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) != RESET) && (timeout > 0))
+ {
+ timeout--;
+ }
+
+ timeout = Timeout;
+
+ while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == RESET) && (timeout > 0))
+ {
+ timeout--;
+ }
+
+ /* Get the NOR memory operation status -------------------------------------*/
+ while((Timeout != 0x00) && (status != NOR_SUCCESS))
+ {
+ Timeout--;
+
+ /* Read DQ6 and DQ5 */
+ val1 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
+ val2 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
+
+ /* If DQ6 did not toggle between the two reads then return NOR_Success */
+ if((val1 & 0x0040) == (val2 & 0x0040))
+ {
+ return NOR_SUCCESS;
+ }
+
+ if((val1 & 0x0020) != 0x0020)
+ {
+ status = NOR_ONGOING;
+ }
+
+ val1 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
+ val2 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
+
+ if((val1 & 0x0040) == (val2 & 0x0040))
+ {
+ return NOR_SUCCESS;
+ }
+ else if((val1 & 0x0020) == 0x0020)
+ {
+ return NOR_ERROR;
+ }
+ }
+
+ if(Timeout == 0x00)
+ {
+ status = NOR_TIMEOUT;
+ }
+
+ /* Return the operation status */
+ return (status);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/spi_if.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/spi_if.c
new file mode 100644
index 0000000..8588f39
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/spi_if.c
@@ -0,0 +1,110 @@
+/**
+ ******************************************************************************
+ * @file spi_if.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief specific media access Layer for SPI flash
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "hw_config.h"
+#include "spi_if.h"
+#include "dfu_mal.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : SPI_If_Init
+* Description : Initializes the Media on the STM32
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t SPI_If_Init(void)
+{
+ sFLASH_Init();
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : SPI_If_Erase
+* Description : Erase sector
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t SPI_If_Erase(uint32_t SectorAddress)
+{
+ sFLASH_EraseSector(SectorAddress);
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : SPI_If_Write
+* Description : Write sectors
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t SPI_If_Write(uint32_t SectorAddress, uint32_t DataLength)
+{
+ uint32_t idx, pages;
+
+ pages = (((DataLength & 0xFF00)) >> 8);
+
+ if (DataLength & 0xFF) /* Not a 256 aligned data */
+ {
+ for ( idx = DataLength; idx < ((DataLength & 0xFF00) + 0x100) ; idx++)
+ {
+ MAL_Buffer[idx] = 0xFF;
+ }
+ pages = (((DataLength & 0xFF00)) >> 8 ) + 1;
+ }
+
+ for (idx = 0; idx < pages; idx++)
+ {
+ sFLASH_WritePage(&MAL_Buffer[idx*256], SectorAddress, 256);
+ SectorAddress += 0x100;
+ }
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : SPI_If_Read
+* Description : Read sectors
+* Input : None
+* Output : None
+* Return : buffer address pointer
+*******************************************************************************/
+uint8_t *SPI_If_Read(uint32_t SectorAddress, uint32_t DataLength)
+{
+ sFLASH_ReadBuffer(MAL_Buffer, SectorAddress, (uint16_t)DataLength);
+ return MAL_Buffer;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f30x.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f30x.c
new file mode 100644
index 0000000..31faf5c
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f30x.c
@@ -0,0 +1,382 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f30x.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ * This file contains the system clock configuration for STM32F30x devices,
+ * and is generated by the clock configuration tool
+ * stm32f30x_Clock_Configuration_V1.0.0.xls
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ * and Divider factors, AHB/APBx prescalers and Flash settings),
+ * depending on the configuration made in the clock xls tool.
+ * This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f30x.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (8 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f30x.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ * function will do nothing and HSI still used as system clock source. User can
+ * add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define
+ * in "stm32f30x.h" file. When HSE is used as system clock source, directly or
+ * through PLL, and you are using different crystal you have to adapt the HSE
+ * value to your own configuration.
+ *
+ * 5. This file configures the system clock as follows:
+ *=============================================================================
+ * Supported STM32F30x device
+ *-----------------------------------------------------------------------------
+ * System Clock source | PLL (HSE)
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 72000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 72000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 2
+ *-----------------------------------------------------------------------------
+ * HSE Frequency(Hz) | 8000000
+ *----------------------------------------------------------------------------
+ * PLLMUL | 9
+ *-----------------------------------------------------------------------------
+ * PREDIV | 1
+ *-----------------------------------------------------------------------------
+ * USB Clock | ENABLE
+ *-----------------------------------------------------------------------------
+ * Flash Latency(WS) | 2
+ *-----------------------------------------------------------------------------
+ * Prefetch Buffer | ON
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f30x_system
+ * @{
+ */
+
+/** @addtogroup STM32F30x_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f30x.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F30x_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F30x_System_Private_Defines
+ * @{
+ */
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F30x_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F30x_System_Private_Variables
+ * @{
+ */
+
+ uint32_t SystemCoreClock = 72000000;
+
+ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F30x_System_Private_FunctionPrototypes
+ * @{
+ */
+
+static void SetSysClock(void);
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F30x_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemFrequency variable.
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+ #endif
+
+ /* Reset the RCC clock configuration to the default reset state ------------*/
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset CFGR register */
+ RCC->CFGR &= 0xF87FC00C;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
+ RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+ /* Reset PREDIV1[3:0] bits */
+ RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
+
+ /* Reset USARTSW[1:0], I2CSW and TIMs bits */
+ RCC->CFGR3 &= (uint32_t)0xFF00FCCC;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+ /* Configure the System clock source, PLL Multiplier and Divider factors,
+ AHB/APBx prescalers and Flash settings ----------------------------------*/
+ SetSysClock();
+
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f30x.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f30x.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock */
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+ pllmull = ( pllmull >> 18) + 2;
+
+ if (pllsource == 0x00)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+ }
+ else
+ {
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ }
+ break;
+ default: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+/**
+ * @brief Configures the System clock source, PLL Multiplier and Divider factors,
+ * AHB/APBx prescalers and Flash settings
+ * @note This function should be called only once the RCC clock configuration
+ * is reset to the default reset state (done in SystemInit() function).
+ * @param None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+ __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+
+/******************************************************************************/
+/* PLL (clocked by HSE) used as System clock source */
+/******************************************************************************/
+
+ /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------*/
+ /* Enable HSE */
+ RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+
+ /* Wait till HSE is ready and if Time out is reached exit */
+ do
+ {
+ HSEStatus = RCC->CR & RCC_CR_HSERDY;
+ StartUpCounter++;
+ } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+ {
+ HSEStatus = (uint32_t)0x01;
+ }
+ else
+ {
+ HSEStatus = (uint32_t)0x00;
+ }
+
+ if (HSEStatus == (uint32_t)0x01)
+ {
+ /* Enable Prefetch Buffer and set Flash Latency */
+ FLASH->ACR = FLASH_ACR_PRFTBE | (uint32_t)FLASH_ACR_LATENCY_1;
+
+ /* HCLK = SYSCLK / 1 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK2 = HCLK / 1 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+
+ /* PCLK1 = HCLK / 2 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
+
+ /* PLL configuration */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL9);
+
+ /* Enable PLL */
+ RCC->CR |= RCC_CR_PLLON;
+
+ /* Wait till PLL is ready */
+ while((RCC->CR & RCC_CR_PLLRDY) == 0)
+ {
+ }
+
+ /* Select PLL as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
+
+ /* Wait till PLL is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
+ {
+ }
+ }
+ else
+ { /* If HSE fails to start-up, the application will have wrong clock
+ configuration. User can add here some code to deal with this error */
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f37x.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f37x.c
new file mode 100644
index 0000000..943f188
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/system_stm32f37x.c
@@ -0,0 +1,380 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f37x.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ * This file contains the system clock configuration for STM32F37x devices,
+ * and is generated by the clock configuration tool
+ * STM32f37x_Clock_Configuration_V1.0.0.xls
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ * and Divider factors, AHB/APBx prescalers and Flash settings),
+ * depending on the configuration made in the clock xls tool.
+ * This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f37x.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (8 MHz Range) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f37x.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ * function will do nothing and HSI still used as system clock source. User can
+ * add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" defined
+ * in "stm32f37x.h" file. When HSE is used as system clock source, directly or
+ * through PLL, and you are using different crystal you have to adapt the HSE
+ * value to your own configuration.
+ *
+ * 5. This file configures the system clock as follows:
+ *=============================================================================
+ * Supported STM32F37x device
+ *=============================================================================
+ * System Clock source | PLL (HSE)
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 72000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 72000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 2
+ *-----------------------------------------------------------------------------
+ * HSE Frequency(Hz) | 8000000
+ *----------------------------------------------------------------------------
+ * PLLMUL | 9
+ *-----------------------------------------------------------------------------
+ * PREDIV | 1
+ *-----------------------------------------------------------------------------
+ * USB Clock | ENABLE
+ *-----------------------------------------------------------------------------
+ * Flash Latency(WS) | 2
+ *-----------------------------------------------------------------------------
+ * Prefetch Buffer | ON
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup STM32F37x_System
+ * @{
+ */
+
+/** @addtogroup STM32F37x_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f37x.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Defines
+ * @{
+ */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Variables
+ * @{
+ */
+uint32_t SystemCoreClock = 72000000;
+__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_FunctionPrototypes
+ * @{
+ */
+
+static void SetSysClock(void);
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F37x_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontrollers system.
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemCoreClock variable.
+ * @param None
+ * @retval None
+ */
+void SystemInit (void)
+{
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+ #endif
+
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, SDADCPRE and MCOSEL[2:0] bits */
+ RCC->CFGR &= (uint32_t)0x00FF0000;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
+ RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+ /* Reset PREDIV1[3:0] bits */
+ RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
+
+ /* Reset USARTSW[1:0], I2CSW and CECSW bits */
+ RCC->CFGR3 &= (uint32_t)0xFFF0F8C;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
+ SetSysClock();
+
+
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
+#endif
+}
+
+/**
+ * @brief Update SystemCoreClock according to Clock Register Values
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f37x.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f37x.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0, pllmull = 0, pllsource = 0, prediv1factor = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock */
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+ pllmull = ( pllmull >> 18) + 2;
+
+ if (pllsource == 0x00)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+ }
+ else
+ {
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
+ }
+ break;
+ default: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+/**
+ * @brief Configures the System clock frequency, AHB/APBx prescalers and Flash
+ * settings.
+ * @note This function should be called only once the RCC clock configuration
+ * is reset to the default reset state (done in SystemInit() function).
+ * @param None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+ __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+
+/******************************************************************************/
+/* PLL (clocked by HSE) used as System clock source */
+/******************************************************************************/
+
+ /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------*/
+ /* Enable HSE */
+ RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+
+ /* Wait till HSE is ready and if Time out is reached exit */
+ do
+ {
+ HSEStatus = RCC->CR & RCC_CR_HSERDY;
+ StartUpCounter++;
+ } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+ {
+ HSEStatus = (uint32_t)0x01;
+ }
+ else
+ {
+ HSEStatus = (uint32_t)0x00;
+ }
+
+ if (HSEStatus == (uint32_t)0x01)
+ {
+ /* Enable Prefetch Buffer and set Flash Latency */
+ FLASH->ACR = FLASH_ACR_PRFTBE | (uint32_t)FLASH_ACR_LATENCY_1;
+
+ /* HCLK = SYSCLK / 1 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK2 = HCLK / 1 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
+
+ /* PCLK1 = HCLK / 2 */
+ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
+
+ /* PLL configuration */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
+ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL9);
+
+ /* Enable PLL */
+ RCC->CR |= RCC_CR_PLLON;
+
+ /* Wait till PLL is ready */
+ while((RCC->CR & RCC_CR_PLLRDY) == 0)
+ {
+ }
+
+ /* Select PLL as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
+
+ /* Wait till PLL is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
+ {
+ }
+ }
+ else
+ { /* If HSE fails to start-up, the application will have wrong clock
+ configuration. User can add here some code to deal with this error */
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_desc.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_desc.c
new file mode 100644
index 0000000..1646763
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_desc.c
@@ -0,0 +1,489 @@
+/**
+ ******************************************************************************
+ * @file usb_desc.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief Descriptors for Device Firmware Upgrade (DFU)
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_desc.h"
+#include "platform_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+uint8_t DFU_DeviceDescriptor[DFU_SIZ_DEVICE_DESC] =
+ {
+ 0x12, /* bLength */
+ 0x01, /* bDescriptorType */
+ 0x00, /* bcdUSB, version 1.00 */
+ 0x01,
+ 0x00, /* bDeviceClass : See interface */
+ 0x00, /* bDeviceSubClass : See interface*/
+ 0x00, /* bDeviceProtocol : See interface */
+ bMaxPacketSize0, /* bMaxPacketSize0 0x40 = 64 */
+ 0x83, /* idVendor (0483) */
+ 0x04,
+ 0x11, /* idProduct (0xDF11) DFU PiD*/
+ 0xDF,
+ 0x00, /* bcdDevice*/
+ 0x02,
+
+ 0x01, /* iManufacturer : index of string Manufacturer */
+ 0x02, /* iProduct : index of string descriptor of product*/
+ 0x03, /* iSerialNumber : index of string serial number*/
+
+ 0x01 /*bNumConfigurations */
+ };
+
+#ifdef USE_STM3210B_EVAL
+uint8_t DFU_ConfigDescriptor[DFU_SIZ_CONFIG_DESC] =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ 0x02, /* bDescriptorType: Configuration */
+ DFU_SIZ_CONFIG_DESC, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ /* Configuration value */
+ 0x00, /* iConfiguration: */
+ /* Index of string descriptor */
+ /* describing the configuration */
+ 0xC0, /* bmAttributes: */
+ /* Self powered */
+ 0x32, /* MaxPower 100 mA */
+ /* 09 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 0 *********/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x04, /* iInterface: */
+ /* Index of string descriptor */
+ /* 18 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 1 **********/
+
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x01, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x05, /* iInterface: */
+ /* Index of string descriptor */
+ /* 27 */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /*blength = 9 Bytes*/
+ 0x21, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ wTransferSizeB0,
+ wTransferSizeB1, /* TransferSize = 1024 Byte*/
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+ /***********************************************************/
+ /*36*/
+
+ };
+
+#elif defined (USE_STM3210E_EVAL)
+uint8_t DFU_ConfigDescriptor[DFU_SIZ_CONFIG_DESC] =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ 0x02, /* bDescriptorType: Configuration */
+ DFU_SIZ_CONFIG_DESC, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ /* Configuration value */
+ 0x00, /* iConfiguration: */
+ /* Index of string descriptor */
+ /* describing the configuration */
+ 0x80, /* bmAttributes: */
+ /* bus powered */
+ 0x20, /* MaxPower 100 mA: this current is used for detecting Vbus */
+ /* 09 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 0 *********/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x04, /* iInterface: */
+ /* Index of string descriptor */
+ /* 18 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 1 **********/
+
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x01, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x05, /* iInterface: */
+ /* Index of string descriptor */
+ /* 27 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 2 **********/
+
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x02, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x06, /* iInterface: */
+ /* Index of string descriptor */
+ /* 36 */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /*blength = 9 Bytes*/
+ 0x21, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ wTransferSizeB0,
+ wTransferSizeB1, /* TransferSize = 1024 Byte*/
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+ /***********************************************************/
+ /*45*/
+
+ };
+
+#elif defined (USE_STM32L152_EVAL) || defined (USE_STM32L152D_EVAL)
+uint8_t DFU_ConfigDescriptor[DFU_SIZ_CONFIG_DESC] =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ 0x02, /* bDescriptorType: Configuration */
+ DFU_SIZ_CONFIG_DESC, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ /* Configuration value */
+ 0x00, /* iConfiguration: */
+ /* Index of string descriptor */
+ /* describing the configuration */
+ 0xC0, /* bmAttributes: */
+ /* bus powered */
+ 0x32, /* MaxPower 100 mA */
+ /* 09 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 0 *********/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x04, /* iInterface: */
+ /* Index of string descriptor */
+ /* 18 */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /*blength = 9 Bytes*/
+ 0x21, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ wTransferSizeB0,
+ wTransferSizeB1, /* TransferSize = 128 Bytes */
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+ /***********************************************************/
+ /*27*/
+
+ };
+
+#elif defined (USE_STM32373C_EVAL) || defined (USE_STM32303C_EVAL)
+uint8_t DFU_ConfigDescriptor[DFU_SIZ_CONFIG_DESC] =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ 0x02, /* bDescriptorType: Configuration */
+ DFU_SIZ_CONFIG_DESC, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ /* Configuration value */
+ 0x00, /* iConfiguration: */
+ /* Index of string descriptor */
+ /* describing the configuration */
+ 0xC0, /* bmAttributes: */
+ /* bus powered */
+ 0x32, /* MaxPower 100 mA */
+ /* 09 */
+
+ /************ Descriptor of DFU interface 0 Alternate setting 0 *********/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x00, /* bNumEndpoints*/
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */
+ 0x04, /* iInterface: */
+ /* Index of string descriptor */
+ /* 18 */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /*blength = 9 Bytes*/
+ 0x21, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ wTransferSizeB0,
+ wTransferSizeB1, /* TransferSize = 128 Bytes */
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+ /***********************************************************/
+ /*27*/
+
+ };
+
+
+#endif /* USE_STM3210B_EVAL */
+
+uint8_t DFU_StringLangId[DFU_SIZ_STRING_LANGID] =
+ {
+ DFU_SIZ_STRING_LANGID,
+ 0x03,
+ 0x09,
+ 0x04 /* LangID = 0x0409: U.S. English */
+ };
+
+
+uint8_t DFU_StringVendor[DFU_SIZ_STRING_VENDOR] =
+ {
+ DFU_SIZ_STRING_VENDOR,
+ 0x03,
+ /* Manufacturer: "STMicroelectronics" */
+ 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
+ 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
+ 'c', 0, 's', 0
+ };
+
+uint8_t DFU_StringProduct[DFU_SIZ_STRING_PRODUCT] =
+ {
+ DFU_SIZ_STRING_PRODUCT,
+ 0x03,
+ /* Product name: "STM32 DFU" */
+ 'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'D', 0, 'F', 0, 'U', 0
+ };
+
+uint8_t DFU_StringSerial[DFU_SIZ_STRING_SERIAL] =
+ {
+ DFU_SIZ_STRING_SERIAL,
+ 0x03,
+ /* Serial number */
+ 'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0
+ };
+
+#if defined (USE_STM3210B_EVAL) || defined (USE_STM32373C_EVAL) || defined (USE_STM32303C_EVAL)
+uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
+ {
+ DFU_SIZ_STRING_INTERFACE0,
+ 0x03,
+ // Interface 0: "@Internal Flash /0x08000000/12*001Ka,116*001Kg"
+ '@', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'n', 0, 'a', 0, 'l', 0, /* 18 */
+ ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, 'h', 0, ' ', 0, ' ', 0, /* 16 */
+
+ '/', 0, '0', 0, 'x', 0, '0', 0, '8', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, /* 22 */
+
+ '/', 0, '1', 0, '2', 0, '*', 0, '0', 0, '0', 0, '1', 0, 'K', 0, 'a', 0, /* 18 */
+ ',', 0, '1', 0, '1', 0, '6', 0, '*', 0, '0', 0, '0', 0, '1', 0, 'K', 0, 'g', 0, /* 20 */
+ };
+
+#elif defined (USE_STM3210E_EVAL)
+ #ifdef STM32F10X_XL
+uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
+ {
+ DFU_SIZ_STRING_INTERFACE0,
+ 0x03,
+ // Interface 0: "@Internal Flash /0x08000000/06*002Ka,506*002Kg"
+ '@', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'n', 0, 'a', 0, 'l', 0, /* 18 */
+ ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, 'h', 0, ' ', 0, ' ', 0, /* 16 */
+
+ '/', 0, '0', 0, 'x', 0, '0', 0, '8', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, /* 22 */
+
+ '/', 0, '0', 0, '6', 0, '*', 0, '0', 0, '0', 0, '2', 0, 'K', 0, 'a', 0, /* 18 */
+ ',', 0, '5', 0, '0', 0, '6', 0, '*', 0, '0', 0, '0', 0, '2', 0, 'K', 0, 'g', 0, /* 20 */
+ };
+ #else
+uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
+ {
+ DFU_SIZ_STRING_INTERFACE0,
+ 0x03,
+ // Interface 0: "@Internal Flash /0x08000000/06*002Ka,250*002Kg"
+ '@', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'n', 0, 'a', 0, 'l', 0, /* 18 */
+ ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, 'h', 0, ' ', 0, ' ', 0, /* 16 */
+
+ '/', 0, '0', 0, 'x', 0, '0', 0, '8', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, /* 22 */
+
+ '/', 0, '0', 0, '6', 0, '*', 0, '0', 0, '0', 0, '2', 0, 'K', 0, 'a', 0, /* 18 */
+ ',', 0, '2', 0, '5', 0, '0', 0, '*', 0, '0', 0, '0', 0, '2', 0, 'K', 0, 'g', 0, /* 20 */
+ };
+ #endif /* STM32F10X_XL */
+
+#elif defined (USE_STM32L152_EVAL)
+uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
+ {
+ DFU_SIZ_STRING_INTERFACE0,
+ 0x03,
+ // Interface 0: "@Internal Flash /0x08000000/48*256 a,464*256 g"
+ '@', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'n', 0, 'a', 0, 'l', 0, /* 18 */
+ ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, 'h', 0, ' ', 0, ' ', 0, /* 16 */
+
+ '/', 0, '0', 0, 'x', 0, '0', 0, '8', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, /* 22 */
+
+ '/', 0, '4', 0, '8', 0, '*', 0, '2', 0, '5', 0, '6', 0, ' ', 0, 'a', 0, /* 18 */
+ ',', 0, '4', 0, '6', 0, '4', 0, '*', 0, '2', 0, '5', 0, '6', 0, ' ', 0, 'g', 0, /* 20 */
+
+ };
+
+
+#elif defined (USE_STM32L152D_EVAL)
+uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
+ {
+ DFU_SIZ_STRING_INTERFACE0,
+ 0x03,
+ // Interface 0: "@Internal Flash /0x08000000/48*256 a,1488*256 g"
+ '@', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'n', 0, 'a', 0, 'l', 0, /* 18 */
+ ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, 'h', 0, ' ', 0, ' ', 0, /* 16 */
+
+ '/', 0, '0', 0, 'x', 0, '0', 0, '8', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, /* 22 */
+
+ '/', 0, '4', 0, '8', 0, '*', 0, '2', 0, '5', 0, '6', 0, ' ', 0, 'a', 0, /* 18 */
+ ',', 0, '1', 0, '4', 0, '8', 0, '8', 0, '*', 0, '2', 0, '5', 0, '6', 0, ' ', 0, 'g', 0, /* 22 */
+ };
+
+#endif /* USE_STM3210B_EVAL */
+
+#if defined(USE_STM3210B_EVAL) || defined(USE_STM3210E_EVAL)
+uint8_t DFU_StringInterface1[DFU_SIZ_STRING_INTERFACE1] =
+ {
+ DFU_SIZ_STRING_INTERFACE1,
+ 0x03,
+ // Interface 1: "@ SPI Flash: M25P64 /0x00000000/128*064Kg"
+ '@', 0, 'S', 0, 'P', 0, 'I', 0, ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0,
+ 'h', 0, ' ', 0, ':', 0, ' ', 0, 'M', 0, '2', 0, '5', 0, 'P', 0, '6', 0, '4', 0,
+ '/', 0, '0', 0, 'x', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '/', 0, '1', 0, '2', 0, '8', 0, '*', 0, '6', 0, '4', 0, 'K', 0, 'g', 0
+ };
+#endif /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */
+
+#ifdef USE_STM3210E_EVAL
+uint8_t DFU_StringInterface2_1[DFU_SIZ_STRING_INTERFACE2] =
+ {
+ DFU_SIZ_STRING_INTERFACE2,
+ 0x03,
+ // Interface 1: "@ NOR Flash: M29W128 /0x64000000/256*064Kg"
+ '@', 0, 'N', 0, 'O', 0, 'R', 0, ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0,
+ 'h', 0, ' ', 0, ':', 0, ' ', 0, 'M', 0, '2', 0, '9', 0, 'W', 0, '1', 0, '2', 0, '8', 0, 'F', 0,
+ '/', 0, '0', 0, 'x', 0, '6', 0, '4', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '/', 0, '0', 0, '2', 0, '5', 0, '6', 0, '*', 0, '6', 0, '4', 0, 'K', 0, 'g', 0
+ };
+uint8_t DFU_StringInterface2_2[DFU_SIZ_STRING_INTERFACE2] =
+ {
+ DFU_SIZ_STRING_INTERFACE2,
+ 0x03,
+ // Interface 1: "@ NOR Flash: M29W128 /0x64000000/128*128Kg"
+ '@', 0, 'N', 0, 'O', 0, 'R', 0, ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0,
+ 'h', 0, ' ', 0, ':', 0, ' ', 0, 'M', 0, '2', 0, '9', 0, 'W', 0, '1', 0, '2', 0, '8', 0, 'G', 0,
+ '/', 0, '0', 0, 'x', 0, '6', 0, '4', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '/', 0, '1', 0, '2', 0, '8', 0, '*', 0, '1', 0, '2', 0, '8', 0, 'K', 0, 'g', 0
+ };
+
+uint8_t DFU_StringInterface2_3[DFU_SIZ_STRING_INTERFACE2] =
+ {
+ DFU_SIZ_STRING_INTERFACE2,
+ 0x03,
+ // Interface 1: "@ NOR Flash:S29GL128 /0x64000000/128*128Kg"
+ '@', 0, 'N', 0, 'O', 0, 'R', 0, ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0,
+ 'h', 0, ' ', 0, ':', 0, ' ', 0, 'S', 0, '2', 0, '9', 0, 'G', 0, 'L', 0 , '1', 0, '2', 0, '8', 0,
+ '/', 0, '0', 0, 'x', 0, '6', 0, '4', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '/', 0, '1', 0, '2', 0, '8', 0, '*', 0, '1', 0, '2', 0, '8', 0, 'K', 0, 'g', 0
+ };
+#endif /* USE_STM3210E_EVAL */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_prop.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_prop.c
new file mode 100644
index 0000000..addfc43
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_prop.c
@@ -0,0 +1,745 @@
+/**
+ ******************************************************************************
+ * @file usb_prop.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief All processings related to DFU demo
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "hw_config.h"
+#include "usb_conf.h"
+#include "usb_prop.h"
+#include "usb_desc.h"
+#include "usb_pwr.h"
+#include "dfu_mal.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint32_t wBlockNum = 0, wlength = 0;
+uint32_t Manifest_State = Manifest_complete;
+uint32_t Pointer = ApplicationAddress; /* Base Address to Erase, Program or Read */
+
+DEVICE Device_Table =
+ {
+ EP_NUM,
+ 1
+ };
+
+DEVICE_PROP Device_Property =
+ {
+ DFU_init,
+ DFU_Reset,
+ DFU_Status_In,
+ DFU_Status_Out,
+ DFU_Data_Setup,
+ DFU_NoData_Setup,
+ DFU_Get_Interface_Setting,
+ DFU_GetDeviceDescriptor,
+ DFU_GetConfigDescriptor,
+ DFU_GetStringDescriptor,
+ 0, /*DFU_EP0Buffer*/
+ bMaxPacketSize0 /*Max Packet size*/
+ };
+
+USER_STANDARD_REQUESTS User_Standard_Requests =
+ {
+ DFU_GetConfiguration,
+ DFU_SetConfiguration,
+ DFU_GetInterface,
+ DFU_SetInterface,
+ DFU_GetStatus,
+ DFU_ClearFeature,
+ DFU_SetEndPointFeature,
+ DFU_SetDeviceFeature,
+ DFU_SetDeviceAddress
+ };
+
+ONE_DESCRIPTOR Device_Descriptor =
+ {
+ (uint8_t*)DFU_DeviceDescriptor,
+ DFU_SIZ_DEVICE_DESC
+ };
+
+ONE_DESCRIPTOR Config_Descriptor =
+ {
+ (uint8_t*)DFU_ConfigDescriptor,
+ DFU_SIZ_CONFIG_DESC
+ };
+#ifdef USE_STM3210E_EVAL
+ ONE_DESCRIPTOR DFU_String_Descriptor[7] =
+#elif defined(USE_STM3210B_EVAL)
+ ONE_DESCRIPTOR DFU_String_Descriptor[6] =
+#elif defined(USE_STM32L152_EVAL) || defined(USE_STM32L152D_EVAL) ||defined(USE_STM32373C_EVAL) ||defined(USE_STM32303C_EVAL)
+ ONE_DESCRIPTOR DFU_String_Descriptor[5] =
+#endif /* USE_STM3210E_EVAL */
+ {
+ { (uint8_t*)DFU_StringLangId, DFU_SIZ_STRING_LANGID },
+ { (uint8_t*)DFU_StringVendor, DFU_SIZ_STRING_VENDOR },
+ { (uint8_t*)DFU_StringProduct, DFU_SIZ_STRING_PRODUCT },
+ { (uint8_t*)DFU_StringSerial, DFU_SIZ_STRING_SERIAL },
+ { (uint8_t*)DFU_StringInterface0, DFU_SIZ_STRING_INTERFACE0 }
+#ifdef USE_STM3210B_EVAL
+ ,
+ { (uint8_t*)DFU_StringInterface1, DFU_SIZ_STRING_INTERFACE1 }
+#endif /* USE_STM3210B_EVAL */
+#ifdef USE_STM3210E_EVAL
+ ,
+ { (uint8_t*)DFU_StringInterface1, DFU_SIZ_STRING_INTERFACE1 },
+ { (uint8_t*)DFU_StringInterface2_1, DFU_SIZ_STRING_INTERFACE2 }
+#endif /* USE_STM3210E_EVAL */
+ };
+
+/* Extern variables ----------------------------------------------------------*/
+extern uint8_t DeviceState ;
+extern uint8_t DeviceStatus[6];
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : DFU_init.
+* Description : DFU init routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_init(void)
+{
+ DEVICE_INFO *pInfo = &Device_Info;
+
+ /* Update the serial number string descriptor with the data from the unique ID*/
+ Get_SerialNum();
+
+ pInfo->Current_Configuration = 0;
+
+ /* Connect the device */
+ PowerOn();
+
+ /* Perform basic device initialization operations */
+ USB_SIL_Init();
+
+ /* Enable USB interrupts */
+ USB_Interrupts_Config();
+
+ bDeviceState = UNCONNECTED;
+}
+
+/*******************************************************************************
+* Function Name : DFU_Reset.
+* Description : DFU reset routine
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_Reset(void)
+{
+ /* Set DFU_DEVICE as not configured */
+ Device_Info.Current_Configuration = 0;
+
+ /* Current Feature initialization */
+ pInformation->Current_Feature = DFU_ConfigDescriptor[7];
+
+ _SetBTABLE(BTABLE_ADDRESS);
+
+ /* Initialize Endpoint 0 */
+ _SetEPType(ENDP0, EP_CONTROL);
+ _SetEPTxStatus(ENDP0, EP_TX_NAK);
+ _SetEPRxAddr(ENDP0, ENDP0_RXADDR);
+ SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+ _SetEPTxAddr(ENDP0, ENDP0_TXADDR);
+ SetEPTxCount(ENDP0, Device_Property.MaxPacketSize);
+ Clear_Status_Out(ENDP0);
+ SetEPRxValid(ENDP0);
+
+ /* Set this device to response on default address */
+ SetDeviceAddress(0);
+
+ /* Set the new control state of the device to Attached */
+ bDeviceState = ATTACHED;
+}
+/*******************************************************************************
+* Function Name : DFU_SetConfiguration.
+* Description : Update the device state to configured.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_SetConfiguration(void)
+{
+ DEVICE_INFO *pInfo = &Device_Info;
+
+ if (pInfo->Current_Configuration != 0)
+ {
+ /* Device configured */
+ bDeviceState = CONFIGURED;
+ }
+}
+/*******************************************************************************
+* Function Name : DFU_SetConfiguration.
+* Description : Update the device state to addressed.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_SetDeviceAddress (void)
+{
+ bDeviceState = ADDRESSED;
+}
+/*******************************************************************************
+* Function Name : DFU_Status_In.
+* Description : DFU status IN routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_Status_In(void)
+{}
+
+/*******************************************************************************
+* Function Name : DFU_Status_Out.
+* Description : DFU status OUT routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_Status_Out (void)
+{
+ DEVICE_INFO *pInfo = &Device_Info;
+ uint32_t Addr;
+
+ if (pInfo->USBbRequest == DFU_GETSTATUS)
+ {
+ if (DeviceState == STATE_dfuDNBUSY)
+ {
+ if (wBlockNum == 0) /* Decode the Special Command*/
+ {
+ if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1))
+ {}
+ else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5))
+ {
+ Pointer = MAL_Buffer[1];
+ Pointer += MAL_Buffer[2] << 8;
+ Pointer += MAL_Buffer[3] << 16;
+ Pointer += MAL_Buffer[4] << 24;
+ }
+ else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5))
+ {
+ Pointer = MAL_Buffer[1];
+ Pointer += MAL_Buffer[2] << 8;
+ Pointer += MAL_Buffer[3] << 16;
+ Pointer += MAL_Buffer[4] << 24;
+ MAL_Erase(Pointer);
+ }
+ }
+
+ else if (wBlockNum > 1) // Download Command
+ {
+ Addr = ((wBlockNum - 2) * wTransferSize) + Pointer;
+ MAL_Write(Addr, wlength);
+ }
+ wlength = 0;
+ wBlockNum = 0;
+
+ DeviceState = STATE_dfuDNLOAD_SYNC;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ return;
+ }
+ else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/
+ {
+ DFU_write_crc();
+ return;
+ }
+ }
+ return;
+}
+
+/*******************************************************************************
+* Function Name : DFU_Data_Setup.
+* Description : Handle the data class specific requests.
+* Input : RequestNb.
+* Output : None.
+* Return : USB_SUCCESS or USB_UNSUPPORT.
+*******************************************************************************/
+RESULT DFU_Data_Setup(uint8_t RequestNo)
+{
+ uint8_t *(*CopyRoutine)(uint16_t);
+ CopyRoutine = NULL;
+
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ {
+ if (RequestNo == DFU_UPLOAD && (DeviceState == STATE_dfuIDLE
+ || DeviceState == STATE_dfuUPLOAD_IDLE ))
+ {
+ CopyRoutine = UPLOAD;
+ }
+ else if (RequestNo == DFU_DNLOAD && (DeviceState == STATE_dfuIDLE
+ || DeviceState == STATE_dfuDNLOAD_IDLE))
+ {
+ DeviceState = STATE_dfuDNLOAD_SYNC;
+ CopyRoutine = DNLOAD;
+ }
+ else if (RequestNo == DFU_GETSTATE)
+ {
+ CopyRoutine = GETSTATE;
+ }
+ else if (RequestNo == DFU_GETSTATUS)
+ {
+ CopyRoutine = GETSTATUS;
+ }
+ else
+ {
+ return USB_UNSUPPORT;
+ }
+ }
+ else
+ {
+ return USB_UNSUPPORT;
+ }
+
+ if (CopyRoutine == NULL)
+ {
+ return USB_UNSUPPORT;
+ }
+
+ pInformation->Ctrl_Info.CopyData = CopyRoutine;
+ pInformation->Ctrl_Info.Usb_wOffset = 0;
+ (*CopyRoutine)(0);
+
+ return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name : DFU_NoData_Setup.
+* Description : Handle the No data class specific requests.
+* Input : Request Nb.
+* Output : None.
+* Return : USB_SUCCESS or USB_UNSUPPORT.
+*******************************************************************************/
+RESULT DFU_NoData_Setup(uint8_t RequestNo)
+{
+
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ {
+ /*DFU_NDLOAD*/
+ if (RequestNo == DFU_DNLOAD)
+ {
+ /* End of DNLOAD operation*/
+ if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE )
+ {
+ Manifest_State = Manifest_In_Progress;
+ DeviceState = STATE_dfuMANIFEST_SYNC;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ DeviceStatus[4] = DeviceState;
+ return USB_SUCCESS;
+ }
+ }
+ /*DFU_UPLOAD*/
+ else if (RequestNo == DFU_UPLOAD)
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ DeviceStatus[4] = DeviceState;
+ return USB_SUCCESS;
+ }
+
+ /*DFU_CLRSTATUS*/
+ else if (RequestNo == DFU_CLRSTATUS)
+ {
+
+ if (DeviceState == STATE_dfuERROR)
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;/*bStatus*/
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;/*bState*/
+ DeviceStatus[5] = 0;/*iString*/
+ }
+ else
+ { /*State Error*/
+ DeviceState = STATE_dfuERROR;
+ DeviceStatus[0] = STATUS_ERRUNKNOWN;/*bStatus*/
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;/*bState*/
+ DeviceStatus[5] = 0;/*iString*/
+ }
+ return USB_SUCCESS;
+ }
+ /*DFU_ABORT*/
+ else if (RequestNo == DFU_ABORT)
+ {
+ if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC
+ || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC
+ || DeviceState == STATE_dfuUPLOAD_IDLE )
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[5] = 0; /*iString*/
+ wBlockNum = 0;
+ wlength = 0;
+ }
+ return USB_SUCCESS;
+ }
+ }
+
+
+ return USB_UNSUPPORT;
+
+} /* End of DFU_NoData_Setup */
+
+/*******************************************************************************
+* Function Name : DFU_GetDeviceDescriptor.
+* Description : Gets the device descriptor.
+* Input : Length.
+* Output : None.
+* Return : The address of the device descriptor.
+*******************************************************************************/
+uint8_t *DFU_GetDeviceDescriptor(uint16_t Length)
+{
+ return Standard_GetDescriptorData(Length, &Device_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name : DFU_GetConfigDescriptor.
+* Description : Gets the configuration descriptor.
+* Input : Length.
+* Output : None.
+* Return : The address of the configuration descriptor.
+*******************************************************************************/
+uint8_t *DFU_GetConfigDescriptor(uint16_t Length)
+{
+ return Standard_GetDescriptorData (Length, &Config_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name : DFU_GetStringDescriptor.
+* Description : Gets the string descriptors according to the needed index.
+* Input : Length.
+* Output : None.
+* Return : The address of the string descriptors.
+*******************************************************************************/
+uint8_t *DFU_GetStringDescriptor(uint16_t Length)
+{
+ uint8_t wValue0 = pInformation->USBwValue0;
+
+ if (wValue0 > 8)
+ {
+ return NULL;
+ }
+ else
+ {
+ return Standard_GetDescriptorData(Length, &DFU_String_Descriptor[wValue0]);
+ }
+}
+
+/*******************************************************************************
+* Function Name : DFU_Get_Interface_Setting.
+* Description : tests the interface and the alternate setting according to the
+* supported one.
+* Input : - Interface : interface number.
+* - AlternateSetting : Alternate Setting number.
+* Output : None.
+* Return : USB_SUCCESS or USB_UNSUPPORT.
+*******************************************************************************/
+RESULT DFU_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
+{
+ if (AlternateSetting > 3)
+ {
+ return USB_UNSUPPORT; /* In this application we don't have more than 3 AlternateSettings */
+ }
+ else if (Interface > 2)
+ {
+ return USB_UNSUPPORT; /* In this application we have only 1 interfaces */
+ }
+
+ return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name : UPLOAD
+* Description : Upload routine.
+* Input : Length.
+* Output : None.
+* Return : Pointer to data.
+*******************************************************************************/
+uint8_t *UPLOAD(uint16_t Length)
+{
+ DEVICE_INFO *pInfo = &Device_Info;
+ uint8_t B1, B0;
+ uint16_t offset, returned;
+ uint8_t *Phy_Addr = NULL;
+ uint32_t Addr = 0;
+
+ B0 = pInfo->USBwValues.bw.bb0;
+ B1 = pInfo->USBwValues.bw.bb1;
+ wBlockNum = (uint16_t)B1;
+ wBlockNum = wBlockNum * 0x100;
+ wBlockNum += (uint16_t)B0; /* wBlockNum value updated*/
+
+ B0 = pInfo->USBwLengths.bw.bb0;
+ B1 = pInfo->USBwLengths.bw.bb1;
+ wlength = (uint16_t)B0;
+ wlength = wlength * 0x100;
+ wlength += (uint16_t)B1; /* wlength value updated*/
+
+ offset = pInformation->Ctrl_Info.Usb_wOffset;
+
+ if (wBlockNum == 0) /* Get Command */
+ {
+ if (wlength > 3)
+ {
+ DeviceState = STATE_dfuIDLE ;
+ }
+ else
+ {
+ DeviceState = STATE_dfuUPLOAD_IDLE;
+ }
+
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ MAL_Buffer[0] = CMD_GETCOMMANDS;
+ MAL_Buffer[1] = CMD_SETADDRESSPOINTER;
+ MAL_Buffer[2] = CMD_ERASE;
+
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = 3 ;
+ return NULL;
+ }
+
+ return(&MAL_Buffer[0]);
+ }
+ else if (wBlockNum > 1)
+ {
+ DeviceState = STATE_dfuUPLOAD_IDLE ;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ Addr = ((wBlockNum - 2) * wTransferSize) + Pointer; /* Change is Accelerated*/
+
+ Phy_Addr = MAL_Read(Addr, wlength);
+ returned = wlength - offset;
+
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = returned ;
+ return NULL;
+ }
+ return(Phy_Addr + offset);
+ }
+ else /* unsupported wBlockNum */
+ {
+ DeviceState = STATUS_ERRSTALLEDPKT;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ return NULL;
+ }
+}
+
+/*******************************************************************************
+* Function Name : DNLOAD
+* Description : Download routine.
+* Input : Length.
+* Output : None.
+* Return : Pointer to data.
+*******************************************************************************/
+uint8_t *DNLOAD (uint16_t Length)
+{
+ DEVICE_INFO *pInfo = &Device_Info;
+ uint8_t B1, B0;
+ uint16_t offset, returned;
+
+ B0 = pInfo->USBwValues.bw.bb0;
+ B1 = pInfo->USBwValues.bw.bb1;
+ wBlockNum = (uint16_t)B1;
+ wBlockNum = wBlockNum * 0x100;
+ wBlockNum += (uint16_t)B0;
+ B0 = pInfo->USBwLengths.bw.bb0;
+ B1 = pInfo->USBwLengths.bw.bb1;
+ wlength = (uint16_t)B0;
+ wlength = wlength * 0x100;
+ wlength += (uint16_t)B1;
+
+ offset = pInfo->Ctrl_Info.Usb_wOffset;
+
+ DeviceState = STATE_dfuDNLOAD_SYNC;
+ DeviceStatus[4] = DeviceState;
+
+ returned = wlength - offset;
+
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = returned ;
+ return NULL;
+ }
+
+ return((uint8_t*)MAL_Buffer + offset);
+}
+
+/*******************************************************************************
+* Function Name : GETSTATE.
+* Description : Get State request routine.
+* Input : Length.
+* Output : None.
+* Return : Pointer to data.
+*******************************************************************************/
+uint8_t *GETSTATE(uint16_t Length)
+{
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = 1 ;
+ return NULL;
+ }
+ else
+ return(&DeviceState);
+}
+
+/*******************************************************************************
+* Function Name : GETSTATUS.
+* Description : Get Status request routine.
+* Input : Length.
+* Output : None.
+* Return : Pointer to data.
+*******************************************************************************/
+uint8_t *GETSTATUS(uint16_t Length)
+{
+ switch (DeviceState)
+ {
+ case STATE_dfuDNLOAD_SYNC:
+ if (wlength != 0)
+ {
+ DeviceState = STATE_dfuDNBUSY;
+ DeviceStatus[4] = DeviceState;
+ if ((wBlockNum == 0) && (MAL_Buffer[0] == CMD_ERASE))
+ {
+ MAL_GetStatus(Pointer, 0, DeviceStatus);
+ }
+ else
+ {
+ MAL_GetStatus(Pointer, 1, DeviceStatus);
+ }
+ }
+ else /* (wlength==0)*/
+ {
+ DeviceState = STATE_dfuDNLOAD_IDLE;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ }
+ break;
+ case STATE_dfuMANIFEST_SYNC :
+ if (Manifest_State == Manifest_In_Progress)
+ {
+ DeviceState = STATE_dfuMANIFEST;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 1; /*bwPollTimeout = 1ms*/
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ //break;
+ }
+ else if (Manifest_State == Manifest_complete && Config_Descriptor.Descriptor[20]
+ & 0x04)
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ //break;
+ }
+ break;
+ default :
+ break;
+ }
+
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = 6 ;
+ return NULL;
+ }
+ else
+ return(&(DeviceStatus[0]));
+}
+
+/*******************************************************************************
+* Function Name : DFU_write_crc.
+* Description : DFU Write CRC routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void DFU_write_crc(void)
+{
+ Manifest_State = Manifest_complete;
+
+ if (Config_Descriptor.Descriptor[20] & 0x04)
+ {
+ DeviceState = STATE_dfuMANIFEST_SYNC;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ return;
+ }
+ else
+ {
+ DeviceState = STATE_dfuMANIFEST_WAIT_RESET;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ Reset_Device();
+
+ return;
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_pwr.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_pwr.c
new file mode 100644
index 0000000..a2253a8
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Projects/Device_Firmware_Upgrade/src/usb_pwr.c
@@ -0,0 +1,318 @@
+/**
+ ******************************************************************************
+ * @file usb_pwr.c
+ * @author MCD Application Team
+ * @version V4.0.0
+ * @date 21-January-2013
+ * @brief Connection/disconnection & power management
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_conf.h"
+#include "usb_pwr.h"
+#include "hw_config.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
+__IO bool fSuspendEnabled = TRUE; /* true when suspend is possible */
+__IO uint32_t EP[8];
+
+struct
+{
+ __IO RESUME_STATE eState;
+ __IO uint8_t bESOFcnt;
+}
+ResumeS;
+
+__IO uint32_t remotewakeupon=0;
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name : PowerOn
+* Description :
+* Input : None.
+* Output : None.
+* Return : USB_SUCCESS.
+*******************************************************************************/
+RESULT PowerOn(void)
+{
+ uint16_t wRegVal;
+
+ /*** cable plugged-in ? ***/
+ USB_Cable_Config(ENABLE);
+
+ /*** CNTR_PWDN = 0 ***/
+ wRegVal = CNTR_FRES;
+ _SetCNTR(wRegVal);
+
+ /*** CNTR_FRES = 0 ***/
+ wInterrupt_Mask = 0;
+ _SetCNTR(wInterrupt_Mask);
+ /*** Clear pending interrupts ***/
+ _SetISTR(0);
+ /*** Set interrupt mask ***/
+ wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
+ _SetCNTR(wInterrupt_Mask);
+
+ return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name : PowerOff
+* Description : handles switch-off conditions
+* Input : None.
+* Output : None.
+* Return : USB_SUCCESS.
+*******************************************************************************/
+RESULT PowerOff()
+{
+ /* disable all interrupts and force USB reset */
+ _SetCNTR(CNTR_FRES);
+ /* clear interrupt status register */
+ _SetISTR(0);
+ /* Disable the Pull-Up*/
+ USB_Cable_Config(DISABLE);
+ /* switch-off device */
+ _SetCNTR(CNTR_FRES + CNTR_PDWN);
+ /* sw variables reset */
+ /* ... */
+
+ return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name : Suspend
+* Description : sets suspend mode operating conditions
+* Input : None.
+* Output : None.
+* Return : USB_SUCCESS.
+*******************************************************************************/
+void Suspend(void)
+{
+ uint32_t i =0;
+ uint16_t wCNTR;
+ uint32_t tmpreg = 0;
+ __IO uint32_t savePWR_CR=0;
+ /* suspend preparation */
+ /* ... */
+
+ /*Store CNTR value */
+ wCNTR = _GetCNTR();
+
+ /* This a sequence to apply a force RESET to handle a robustness case */
+
+ /*Store endpoints registers status */
+ for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);
+
+ /* unmask RESET flag */
+ wCNTR|=CNTR_RESETM;
+ _SetCNTR(wCNTR);
+
+ /*apply FRES */
+ wCNTR|=CNTR_FRES;
+ _SetCNTR(wCNTR);
+
+ /*clear FRES*/
+ wCNTR&=~CNTR_FRES;
+ _SetCNTR(wCNTR);
+
+ /*poll for RESET flag in ISTR*/
+ while((_GetISTR()&ISTR_RESET) == 0);
+
+ /* clear RESET flag in ISTR */
+ _SetISTR((uint16_t)CLR_RESET);
+
+ /*restore Enpoints*/
+ for (i=0;i<8;i++)
+ _SetENDPOINT(i, EP[i]);
+
+ /* Now it is safe to enter macrocell in suspend mode */
+ wCNTR |= CNTR_FSUSP;
+ _SetCNTR(wCNTR);
+
+ /* force low-power mode in the macrocell */
+ wCNTR = _GetCNTR();
+ wCNTR |= CNTR_LPMODE;
+ _SetCNTR(wCNTR);
+
+ /*prepare entry in low power mode (STOP mode)*/
+ /* Select the regulator state in STOP mode*/
+ savePWR_CR = PWR->CR;
+ tmpreg = PWR->CR;
+ /* Clear PDDS and LPDS bits */
+ tmpreg &= ((uint32_t)0xFFFFFFFC);
+ /* Set LPDS bit according to PWR_Regulator value */
+ tmpreg |= PWR_Regulator_LowPower;
+ /* Store the new value */
+ PWR->CR = tmpreg;
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+#if defined (STM32F30X) || defined (STM32F37X)
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+#else
+ SCB->SCR |= SCB_SCR_SLEEPDEEP;
+#endif
+
+ /* enter system in STOP mode, only when wakeup flag in not set */
+ if((_GetISTR()&ISTR_WKUP)==0)
+ {
+ __WFI();
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+#if defined (STM32F30X) || defined (STM32F37X)
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+#else
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
+#endif
+ }
+ else
+ {
+ /* Clear Wakeup flag */
+ _SetISTR(CLR_WKUP);
+ /* clear FSUSP to abort entry in suspend mode */
+ wCNTR = _GetCNTR();
+ wCNTR&=~CNTR_FSUSP;
+ _SetCNTR(wCNTR);
+
+ /*restore sleep mode configuration */
+ /* restore Power regulator config in sleep mode*/
+ PWR->CR = savePWR_CR;
+
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+#if defined (STM32F30X) || defined (STM32F37X)
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+#else
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
+#endif
+ }
+}
+
+/*******************************************************************************
+* Function Name : Resume_Init
+* Description : Handles wake-up restoring normal operations
+* Input : None.
+* Output : None.
+* Return : USB_SUCCESS.
+*******************************************************************************/
+void Resume_Init(void)
+{
+ uint16_t wCNTR;
+
+ /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
+ /* restart the clocks */
+ /* ... */
+
+ /* CNTR_LPMODE = 0 */
+ wCNTR = _GetCNTR();
+ wCNTR &= (~CNTR_LPMODE);
+ _SetCNTR(wCNTR);
+
+ /* restore full power */
+ /* ... on connected devices */
+ Leave_LowPowerMode();
+
+ /* reset FSUSP bit */
+ _SetCNTR(IMR_MSK);
+
+ /* reverse suspend preparation */
+ /* ... */
+
+}
+
+/*******************************************************************************
+* Function Name : Resume
+* Description : This is the state machine handling resume operations and
+* timing sequence. The control is based on the Resume structure
+* variables and on the ESOF interrupt calling this subroutine
+* without changing machine state.
+* Input : a state machine value (RESUME_STATE)
+* RESUME_ESOF doesn't change ResumeS.eState allowing
+* decrementing of the ESOF counter in different states.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void Resume(RESUME_STATE eResumeSetVal)
+{
+ uint16_t wCNTR;
+
+ if (eResumeSetVal != RESUME_ESOF)
+ ResumeS.eState = eResumeSetVal;
+ switch (ResumeS.eState)
+ {
+ case RESUME_EXTERNAL:
+ if (remotewakeupon ==0)
+ {
+ Resume_Init();
+ ResumeS.eState = RESUME_OFF;
+ }
+ else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
+ {
+ ResumeS.eState = RESUME_ON;
+ }
+ break;
+ case RESUME_INTERNAL:
+ Resume_Init();
+ ResumeS.eState = RESUME_START;
+ remotewakeupon = 1;
+ break;
+ case RESUME_LATER:
+ ResumeS.bESOFcnt = 2;
+ ResumeS.eState = RESUME_WAIT;
+ break;
+ case RESUME_WAIT:
+ ResumeS.bESOFcnt--;
+ if (ResumeS.bESOFcnt == 0)
+ ResumeS.eState = RESUME_START;
+ break;
+ case RESUME_START:
+ wCNTR = _GetCNTR();
+ wCNTR |= CNTR_RESUME;
+ _SetCNTR(wCNTR);
+ ResumeS.eState = RESUME_ON;
+ ResumeS.bESOFcnt = 10;
+ break;
+ case RESUME_ON:
+ ResumeS.bESOFcnt--;
+ if (ResumeS.bESOFcnt == 0)
+ {
+ wCNTR = _GetCNTR();
+ wCNTR &= (~CNTR_RESUME);
+ _SetCNTR(wCNTR);
+ ResumeS.eState = RESUME_OFF;
+ remotewakeupon = 0;
+ }
+ break;
+ case RESUME_OFF:
+ case RESUME_ESOF:
+ default:
+ ResumeS.eState = RESUME_OFF;
+ break;
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/