/** ****************************************************************************** * @file bsp_gui.c * @author MCD Application Team * @brief This file contains phy interface control functions. ****************************************************************************** * @attention * *

© Copyright (c) 2018 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #if defined(_GUI_INTERFACE) #include "bsp_gui.h" #include "usbpd_dpm_conf.h" #if GUI_FLASH_MAGIC_NUMBER #include "usbpd_trace.h" #include "tracer_emb.h" #endif /* GUI_FLASH_MAGIC_NUMBER */ /* Private typedef -----------------------------------------------------------*/ /* Private Defines */ extern USBPD_SettingsTypeDef DPM_Settings[USBPD_PORT_COUNT]; extern uint8_t USBPD_NbPDO[4]; #if defined(_VDM) extern USBPD_VDM_SettingsTypeDef DPM_VDM_Settings[USBPD_PORT_COUNT]; #endif /* _VDM */ #if GUI_FLASH_MAGIC_NUMBER uint64_t MagicNumber = 0xDEADBABEDEADF00DU; #endif /* GUI_FLASH_MAGIC_NUMBER */ /* Private Macro */ #if GUI_FLASH_MAGIC_NUMBER #define GUI_CHECK_IF_MEMORY_IS_CORRUPTED(__ADDR__) #else #define GUI_CHECK_IF_MEMORY_IS_CORRUPTED(__ADDR__) if (0xFFFFFFFFu != *((uint32_t*)(__ADDR__))) #endif /* GUI_FLASH_MAGIC_NUMBER */ /* Private function prototypes -----------------------------------------------*/ static GUI_StatusTypeDef LoadPDOFromFlash(uint32_t Address, uint32_t *pListOfPDO); static GUI_StatusTypeDef LoadSettingsFromFlash(uint32_t Address, uint32_t *pSettings, uint32_t Size); static GUI_StatusTypeDef SavePDOInFlash(uint32_t Address, uint32_t* pListOfPDO); static GUI_StatusTypeDef SaveSettingsInFlash(uint32_t Address, uint32_t *pSettings, uint32_t Size); GUI_StatusTypeDef BSP_GUI_LoadDataFromFlash(void) { GUI_StatusTypeDef _status = GUI_ERROR; #if GUI_FLASH_MAGIC_NUMBER uint32_t _addr = GUI_FLASH_MAGIC_NUMBER; #else uint32_t _addr = GUI_FLASH_ADDR_NB_PDO_SNK_P0; #endif /* GUI_FLASH_MAGIC_NUMBER */ /* Check that we did not reach the end of page */ if (GUI_FLASH_SIZE_RESERVED < 0) { goto _exit; } #if GUI_FLASH_MAGIC_NUMBER /* check that GUI area has not been corrupted */ if ((0xFFFFFFFFu != *((uint32_t*)_addr)) && (MagicNumber != *((uint64_t*)_addr))) { /* Memory has been corrupted */ USBPD_TRACE_Add(USBPD_TRACE_DEBUG, 0U, 0U, (uint8_t*)"GUI Memory is corrupted", sizeof("GUI Memory is corrupted")); goto _exit; } if (0xFFFFFFFFu == *((uint32_t*)_addr)) { /* Memory is empty no need to retrieve data from GUI area */ goto _exit; } _addr = GUI_FLASH_ADDR_NB_PDO_SNK_P0; #endif /* GUI_FLASH_MAGIC_NUMBER */ GUI_CHECK_IF_MEMORY_IS_CORRUPTED(_addr) { uint32_t* _ptr = (uint32_t*)USBPD_NbPDO; USPBPD_WRITE32 (_ptr,*((uint32_t*)_addr)); _status = GUI_OK; } #if defined(_SRC) || defined(_DRP) /* Save PORT0_PDO_ListSRC */ _status |= LoadPDOFromFlash(GUI_FLASH_ADDR_PDO_SRC_P0, PORT0_PDO_ListSRC); #endif /* _SRC || _DRP */ #if defined(_SNK) || defined(_DRP) /* Save PORT0_PDO_ListSNK */ _status |= LoadPDOFromFlash(GUI_FLASH_ADDR_PDO_SNK_P0, PORT0_PDO_ListSNK); #endif /* _SNK || _DRP */ #if USBPD_PORT_COUNT==2 #if defined(_SRC) || defined(_DRP) /* Save PORT1_PDO_ListSRC */ _status |= LoadPDOFromFlash(GUI_FLASH_ADDR_PDO_SRC_P1, PORT1_PDO_ListSRC); #endif /* _SRC || _DRP */ #if defined(_SNK) || defined(_DRP) /* Save PORT1_PDO_ListSNK */ _status |= LoadPDOFromFlash(GUI_FLASH_ADDR_PDO_SNK_P1, PORT1_PDO_ListSNK); #endif /* _SNK || _DRP */ #endif /* USBPD_PORT_COUNT==2 */ /* Save DPM_Settings of port 0 */ _status |= LoadSettingsFromFlash(GUI_FLASH_ADDR_DPM_SETTINGS, (uint32_t*)DPM_Settings, sizeof(USBPD_SettingsTypeDef) * USBPD_PORT_COUNT); #if defined(GUI_FLASH_ADDR_DPM_ID_SETTINGS) /* Save DPM_ID_Settings */ _status |= LoadSettingsFromFlash(GUI_FLASH_ADDR_DPM_ID_SETTINGS, (uint32_t*)DPM_ID_Settings, sizeof(USBPD_IdSettingsTypeDef) * USBPD_PORT_COUNT); #endif /* GUI_FLASH_ADDR_DPM_ID_SETTINGS */ /* Save DPM_Settings of port 0 */ _status |= LoadSettingsFromFlash(GUI_FLASH_ADDR_DPM_USER_SETTINGS, (uint32_t*)DPM_USER_Settings, sizeof(USBPD_USER_SettingsTypeDef) * USBPD_PORT_COUNT); #if defined(GUI_FLASH_ADDR_DPM_ID_SETTINGS) /* Overwrite ID Settings in DPM_USER_Settings */ #if defined(USBPD_REV30_SUPPORT) #if _SRC_CAPA_EXT && (defined(_SRC)||defined(_DRP)) DPM_USER_Settings[USBPD_PORT_0].DPM_SRCExtendedCapa.XID = DPM_ID_Settings[USBPD_PORT_0].XID; DPM_USER_Settings[USBPD_PORT_0].DPM_SRCExtendedCapa.VID = DPM_ID_Settings[USBPD_PORT_0].VID; DPM_USER_Settings[USBPD_PORT_0].DPM_SRCExtendedCapa.PID = DPM_ID_Settings[USBPD_PORT_0].PID; #if USBPD_PORT_COUNT==2 DPM_USER_Settings[USBPD_PORT_1].DPM_SRCExtendedCapa.XID = DPM_ID_Settings[USBPD_PORT_1].XID; DPM_USER_Settings[USBPD_PORT_1].DPM_SRCExtendedCapa.VID = DPM_ID_Settings[USBPD_PORT_1].VID; DPM_USER_Settings[USBPD_PORT_1].DPM_SRCExtendedCapa.PID = DPM_ID_Settings[USBPD_PORT_1].PID; #endif /* USBPD_PORT_COUNT==2 */ #endif /* _SRC_CAPA_EXT && (_SRC || _DRP) */ #if defined(_SNK)||defined(_DRP) DPM_USER_Settings[USBPD_PORT_0].DPM_SNKExtendedCapa.XID = DPM_ID_Settings[USBPD_PORT_0].XID; DPM_USER_Settings[USBPD_PORT_0].DPM_SNKExtendedCapa.VID = DPM_ID_Settings[USBPD_PORT_0].VID; DPM_USER_Settings[USBPD_PORT_0].DPM_SNKExtendedCapa.PID = DPM_ID_Settings[USBPD_PORT_0].PID; #if USBPD_PORT_COUNT==2 DPM_USER_Settings[USBPD_PORT_1].DPM_SNKExtendedCapa.XID = DPM_ID_Settings[USBPD_PORT_1].XID; DPM_USER_Settings[USBPD_PORT_1].DPM_SNKExtendedCapa.VID = DPM_ID_Settings[USBPD_PORT_1].VID; DPM_USER_Settings[USBPD_PORT_1].DPM_SNKExtendedCapa.PID = DPM_ID_Settings[USBPD_PORT_1].PID; #endif /* USBPD_PORT_COUNT==2 */ #endif /* _SNK || _DRP */ #if _MANU_INFO DPM_USER_Settings[USBPD_PORT_0].DPM_ManuInfoPort.VID = DPM_ID_Settings[USBPD_PORT_0].VID; DPM_USER_Settings[USBPD_PORT_0].DPM_ManuInfoPort.PID = DPM_ID_Settings[USBPD_PORT_0].PID; #if USBPD_PORT_COUNT==2 DPM_USER_Settings[USBPD_PORT_1].DPM_ManuInfoPort.VID = DPM_ID_Settings[USBPD_PORT_1].VID; DPM_USER_Settings[USBPD_PORT_1].DPM_ManuInfoPort.PID = DPM_ID_Settings[USBPD_PORT_1].PID; #endif /* USBPD_PORT_COUNT==2 */ #endif /* _MANU_INFO */ #endif /* USBPD_REV30_SUPPORT */ #endif /* GUI_FLASH_ADDR_DPM_ID_SETTINGS */ #if defined(_VDM) /* Save DPM_Settings of port 0 */ _status |= LoadSettingsFromFlash(GUI_FLASH_ADDR_DPM_VDM_SETTINGS, (uint32_t*)DPM_VDM_Settings, sizeof(USBPD_VDM_SettingsTypeDef) * USBPD_PORT_COUNT); #if defined(GUI_FLASH_ADDR_DPM_ID_SETTINGS) /* Overwrite ID Settings in VDM settings */ DPM_VDM_Settings[USBPD_PORT_0].VDM_XID_SOP = DPM_ID_Settings[USBPD_PORT_0].XID; DPM_VDM_Settings[USBPD_PORT_0].VDM_USB_VID_SOP = DPM_ID_Settings[USBPD_PORT_0].VID; DPM_VDM_Settings[USBPD_PORT_0].VDM_PID_SOP = DPM_ID_Settings[USBPD_PORT_0].PID; #if USBPD_PORT_COUNT==2 DPM_VDM_Settings[USBPD_PORT_1].VDM_XID_SOP = DPM_ID_Settings[USBPD_PORT_1].XID; DPM_VDM_Settings[USBPD_PORT_1].VDM_USB_VID_SOP = DPM_ID_Settings[USBPD_PORT_1].VID; DPM_VDM_Settings[USBPD_PORT_1].VDM_PID_SOP = DPM_ID_Settings[USBPD_PORT_1].PID; #endif /* USBPD_PORT_COUNT==2 */ #endif /* _VDM */ #endif /* GUI_FLASH_ADDR_DPM_ID_SETTINGS */ _exit: return _status; } GUI_StatusTypeDef BSP_GUI_SaveDataInFlash(void) { GUI_StatusTypeDef status = GUI_ERROR; FLASH_EraseInitTypeDef erase_init; uint32_t page_error; /* Disable interrupts */ __disable_irq(); /* Init Flash registers for writing */ HAL_FLASH_Unlock(); /* Erase the page associated to the GUI parameters */ erase_init.TypeErase = FLASH_TYPEERASE_PAGES; #if defined(STM32F072xB)|| defined(STM32F051x8) erase_init.PageAddress = ADDR_FLASH_LAST_PAGE; #else erase_init.Page = INDEX_PAGE; #endif /* STM32F072xB || STM32F051x8 */ #if defined (FLASH_OPTR_DBANK) erase_init.Banks = FLASH_BANK_2; #endif /* FLASH_OPTR_DBANK */ erase_init.NbPages = 1; #if defined(FLASH_SR_OPTVERR) /* Specific handling of STM32G0 and STM32G4 flash devices for allowing erase operations */ if(FLASH->SR != 0x00) { FLASH->SR = FLASH_SR_OPTVERR; } #endif status = (HAL_OK == HAL_FLASHEx_Erase(&erase_init, &page_error)) ? GUI_OK : GUI_ERASE_ERROR; /* If Erase is OK, program the new data */ if ((0xFFFFFFFF == page_error) && (GUI_OK == status)) { #if GUI_FLASH_MAGIC_NUMBER /* Save magic Number */ status = (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, GUI_FLASH_MAGIC_NUMBER, MagicNumber)) ? GUI_OK : GUI_WRITE_ERROR; #endif /* GUI_FLASH_MAGIC_NUMBER */ #ifdef GUI_FLASH_ADDR_NB_PDO_SNK_P0 if (GUI_OK == status) { /* Save the nb of sink and src PDO */ uint64_t value = 0; value |= USBPD_NbPDO[0]; value |= (USBPD_NbPDO[1] << 8); value |= (USBPD_NbPDO[2] << 16); value |= (USBPD_NbPDO[3] << 24); status = (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, GUI_FLASH_ADDR_NB_PDO_SNK_P0, value)) ? GUI_OK : GUI_WRITE_ERROR; } #endif /* GUI_FLASH_ADDR_NB_PDO_SNK_P0 */ #if defined(_SRC) || defined(_DRP) /* Save PORT0_PDO_ListSRC */ if (GUI_OK == status) { status = SavePDOInFlash(GUI_FLASH_ADDR_PDO_SRC_P0, PORT0_PDO_ListSRC); } #endif /* _SRC || _DRP */ #if defined(_SNK) || defined(_DRP) /* Save PORT0_PDO_ListSNK */ if (GUI_OK == status) { status = SavePDOInFlash(GUI_FLASH_ADDR_PDO_SNK_P0, PORT0_PDO_ListSNK); } #endif /* _SNK || _DRP */ #if USBPD_PORT_COUNT==2 #if defined(_SRC) || defined(_DRP) /* Save PORT1_PDO_ListSRC */ if (GUI_OK == status) { status = SavePDOInFlash(GUI_FLASH_ADDR_PDO_SRC_P1, PORT1_PDO_ListSRC); } #endif /* _SRC || _DRP */ #if defined(_SNK) || defined(_DRP) /* Save PORT1_PDO_ListSNK */ if (GUI_OK == status) { status = SavePDOInFlash(GUI_FLASH_ADDR_PDO_SNK_P1, PORT1_PDO_ListSNK); } #endif /* _SNK || _DRP */ #endif /* USBPD_PORT_COUNT==2 */ /* Save DPM_Settings of port 0 */ if (GUI_OK == status) { status = SaveSettingsInFlash(GUI_FLASH_ADDR_DPM_SETTINGS, (uint32_t*)DPM_Settings, sizeof(USBPD_SettingsTypeDef) * USBPD_PORT_COUNT); } #if defined(GUI_FLASH_ADDR_DPM_ID_SETTINGS) /* Save DPM_ID_Settings */ if (GUI_OK == status) { status = SaveSettingsInFlash(GUI_FLASH_ADDR_DPM_ID_SETTINGS, (uint32_t*)DPM_ID_Settings, sizeof(USBPD_IdSettingsTypeDef)); } #endif /* GUI_FLASH_ADDR_DPM_ID_SETTINGS */ /* Save DPM_Settings of port 0 */ if (GUI_OK == status) { status = SaveSettingsInFlash(GUI_FLASH_ADDR_DPM_USER_SETTINGS, (uint32_t*)DPM_USER_Settings, sizeof(USBPD_USER_SettingsTypeDef) * USBPD_PORT_COUNT); } #if defined(_VDM) /* Save DPM_Settings of port 0 */ if (GUI_OK == status) { status = SaveSettingsInFlash(GUI_FLASH_ADDR_DPM_VDM_SETTINGS, (uint32_t*)DPM_VDM_Settings, sizeof(USBPD_VDM_SettingsTypeDef) * USBPD_PORT_COUNT); } #endif /* _VDM */ } /* Lock the flash after end of operations */ HAL_FLASH_Lock(); /* Enable interrupts */ __enable_irq(); return status; } static GUI_StatusTypeDef SavePDOInFlash(uint32_t Address, uint32_t *pListOfPDO) { uint64_t data_in_64; uint32_t index, index_flash; uint32_t value[2]; GUI_StatusTypeDef status = GUI_OK; for (index = 0, index_flash = 0; ((index < USBPD_MAX_NB_PDO) && (GUI_OK == status)); index++, index_flash++) { value[0] = pListOfPDO[index]; index++; if (index < USBPD_MAX_NB_PDO) { value[1] = pListOfPDO[index]; } else { value[1] = (0xFFFFFFFF); } data_in_64 = value[0] | (uint64_t)value[1] << 32; /* Save in the FLASH */ status = HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (Address + (8 * index_flash)) , data_in_64) ? GUI_OK : GUI_WRITE_ERROR; } return status; } static GUI_StatusTypeDef SaveSettingsInFlash(uint32_t Address, uint32_t *pSettings, uint32_t Size) { uint64_t data_in_64; uint32_t index, index_flash; uint32_t value[2]; GUI_StatusTypeDef status = GUI_OK; uint32_t nb_double = ((Size * USBPD_PORT_COUNT) / 4); uint8_t remaining = ((Size * USBPD_PORT_COUNT) % 4); /* Save Settings in the FLASH */ for (index = 0, index_flash = 0; ((index < nb_double) && (GUI_OK == status)); index++, index_flash++) { value[0] = pSettings[index]; index++; if (index < nb_double) { value[1] = pSettings[index]; } else { if (0 == remaining) value[1] = (0xFFFFFFFF); else while(1); } data_in_64 = value[0] | (uint64_t)value[1] << 32; /* Save in the FLASH */ status = HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (Address + (8 * index_flash)) , data_in_64)? GUI_OK : GUI_WRITE_ERROR; } return status; } static GUI_StatusTypeDef LoadPDOFromFlash(uint32_t Address, uint32_t *pListOfPDO) { uint32_t _addr = Address; GUI_StatusTypeDef _status = GUI_ERROR; /* Check if FLASH is not empty to retrieve the data. Nethertheless keep data in the RAM */ GUI_CHECK_IF_MEMORY_IS_CORRUPTED(_addr) { uint32_t _index; for (_index = 0; _index < USBPD_MAX_NB_PDO; _index++) { pListOfPDO[_index] = *((uint32_t*)_addr); _addr = _addr + 4u; } _status = GUI_OK; } return _status; } static GUI_StatusTypeDef LoadSettingsFromFlash(uint32_t Address, uint32_t *pSettings, uint32_t Size) { uint32_t _addr = Address; GUI_StatusTypeDef _status = GUI_ERROR; /* Check if FLASH is not empty to retrieve the data. Nethertheless keep data in the RAM */ GUI_CHECK_IF_MEMORY_IS_CORRUPTED(_addr) { memcpy(pSettings, ((uint32_t*)_addr), Size); _status = GUI_OK; } return _status; } #endif /* _GUI_INTERFACE */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/