stm32cubeide/USB-PD_Provider_1port/Utilities/GUI_INTERFACE/gui_api.c

3377 lines
128 KiB
C
Raw Normal View History

2021-01-01 14:06:20 +01:00
/**
******************************************************************************
* @file gui_api.c
* @author MCD Application Team
* @brief GUI_API provides functions associated with answers the MCU can send
to the computer via UART.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* 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
*
******************************************************************************
*/
#if defined(_GUI_INTERFACE)
#define GUI_API_C
#include <stdlib.h>
#include "usbpd_core.h"
#include "gui_api.h"
#include "bsp_gui.h"
#include "data_struct_tlv.h"
#include "usbpd_dpm_core.h"
#include "usbpd_trace.h"
#include "usbpd_dpm_user.h"
#include "usbpd_dpm_conf.h"
#include "tracer_emb.h"
#ifdef _VDM
#include "usbpd_vdm_user.h"
#endif /* _VDM */
#include "usbpd_pdo_defs.h"
#ifndef USBPD_TCPM_MODULE_ENABLED
//#include "usbpd_hw_if.h"
#else
#include "usbpd_tcpci.h"
#endif
#if defined(_RTOS)
#include "cmsis_os.h"
#else
#if defined(USE_STM32_UTILITY_OS)
#include "utilities_conf.h"
#endif /*USE_STM32_UTILITY_OS */
#endif /*_RTOS*/
#include "string.h"
/* generic hal function valid for all stm32 */
extern uint32_t HAL_GetTick(void);
extern void HAL_NVIC_SystemReset(void);
/** @addtogroup STM32_USBPD_LIBRARY
* @{
*/
/** @addtogroup USBPD_GUI_API
* @{
*/
/* Private enums -------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup USBPD_GUI_API_Private_Defines USBPD GUI API Private Defines
* @{
*/
#if !defined(USBPD_FW_VERSION)
#define USBPD_FW_VERSION 0xFFFFFFFFU
#endif /* !USBPD_FW_VERSION */
#if !defined(USBPD_START_PORT_NUMBER)
#define USBPD_START_PORT_NUMBER 0U
#endif /* !USBPD_START_PORT_NUMBER */
#define GUI_PORT_BIT_POSITION 5u /* Bit position of port number in TAG id */
#define GUI_BOX_MESSAGES_MAX 30u
#define GUI_TIMER_ENABLE_MSK ((uint16_t)0x8000U) /*!< Enable Timer Mask */
#define GUI_TIMER_READ_MSK ((uint16_t)0x7FFFU) /*!< Read Timer Mask */
#if defined(USBPDCORE_SNK_CAPA_EXT)
#define GUI_VDM_CABLE_INFO USBPD_CORE_SNK_EXTENDED_CAPA + 1U
#else
#define GUI_VDM_CABLE_INFO USBPD_CORE_UNSTRUCTURED_VDM + 1U
#endif /* USBPDCORE_SNK_CAPA_EXT */
#if defined(_RTOS)
#if (osCMSIS < 0x20000U)
#define GUI_STACK_SIZE_ADDON_FOR_CMSIS 1
#else
#define GUI_STACK_SIZE_ADDON_FOR_CMSIS 5
#endif /* osCMSIS < 0x20000U */
#define FREERTOS_GUI_PRIORITY osPriorityLow
#define FREERTOS_GUI_STACK_SIZE (240 * GUI_STACK_SIZE_ADDON_FOR_CMSIS)
#endif /*_RTOS*/
/**
* @brief USB PD GUI REJECT REASON
*/
typedef enum
{
GUI_REJ_DPM_REJECT = 0x00, /*<! Use in DPM_CONFIG_REJ */
GUI_REJ_DPM_BUSY = 0x01, /*<! Use in DPM_CONFIG_REJ */
GUI_REJ_DPM_TIMEOUT = 0x02, /*<! Use in DPM_CONFIG_REJ */
GUI_REJ_DPM_INVALID_MESSAGE = 0x03, /*<! Use in DPM_CONFIG_REJ (incorrect param in DPM_CONFIG_GET) */
GUI_REJ_DPM_OUT_OF_RANGE = 0x04, /*<! Use in DPM_CONFIG_REJ */
GUI_REJ_DPM_INVALID_PORT_NUMBER = 0x05, /*<! Use in DPM_CONFIG_REJ */
GUI_REJ_DPM_NOT_READY = 0x06, /*<! Use in DPM_MESSAGE_REJ */
} USBPD_GUI_Reject_Reason;
/**
* @brief USB PD GUI REGISTER TCPC
*/
#define GUI_REG_NUMBER_OF_REGISTERS 39
typedef enum
{
GUI_REG_VENDOR_ID = 0x00, /*<! VENDOR_ID */
GUI_REG_PRODUCT_ID = 0x02, /*<! PRODUCT_ID */
GUI_REG_DEVICE_ID = 0x04, /*<! DEVICE_ID */
GUI_REG_USBTYPEC_REV = 0x06, /*<! USBTYPEC_REV */
GUI_REG_USBPD_REV_VER = 0x08, /*<! USBPD_REV_VER */
GUI_REG_USBPD_INTERFACE_REV = 0x0A, /*<! USBPD_INTERFACE_REV */
GUI_REG_ALERT = 0x10, /*<! ALERT */
GUI_REG_ALERT_MASK = 0x12, /*<! ALERT_MASK */
GUI_REG_POWER_STATUS_MASK = 0x14, /*<! POWER_STATUS_MASK */
GUI_REG_FAULT_STATUS_MASK = 0x15, /*<! FAULT_STATUS_MASK */
GUI_REG_CONFIG_STANDARD_OUTPUT = 0x18, /*<! CONFIG_STANDARD_OUTPUT */
GUI_REG_TCPC_CONTROL = 0x19, /*<! TCPC_CONTROL */
GUI_REG_ROLE_CONTROL = 0x1A, /*<! ROLE_CONTROL */
GUI_REG_FAULT_CONTROL = 0x1B, /*<! FAULT_CONTROL */
GUI_REG_POWER_CONTROL = 0x1C, /*<! POWER_CONTROL */
GUI_REG_CC_STATUS = 0x1D, /*<! CC_STATUS */
GUI_REG_POWER_STATUS = 0x1E, /*<! POWER_STATUS */
GUI_REG_FAULT_STATUS = 0x1F, /*<! FAULT_STATUS */
GUI_REG_COMMAND = 0x23, /*<! COMMAND */
GUI_REG_DECIVE_CAP1 = 0x24, /*<! DECIVE_CAP1 */
GUI_REG_DECIVE_CAP2 = 0x26, /*<! DECIVE_CAP2 */
GUI_REG_STD_INPUT_CAP = 0x28, /*<! STD_INPUT_CAP */
GUI_REG_STD_OUTPUT_CAP = 0x29, /*<! STD_OUTPUT_CAP */
GUI_REG_MSG_HEADER_INFO = 0x2E, /*<! MSG_HEADER_INFO */
GUI_REG_RX_DETECT = 0x2F, /*<! RX_DETECT */
GUI_REG_RX_BYTE_COUNT = 0x30, /*<! RX_BYTE_COUNT */
GUI_REG_RX_BUFFER_FRAME_TYPE = 0x31, /*<! RX_BUFFER_FRAME_TYPE */
GUI_REG_RX_HEADER = 0x32, /*<! RX_HEADER */
GUI_REG_RX_DATA = 0x34, /*<! RX_DATA */
GUI_REG_TRANSMIT = 0x50, /*<! TRANSMIT */
GUI_REG_TX_BYTE_COUNT = 0x51, /*<! TX_BYTE_COUNT */
GUI_REG_TX_HEADER = 0x52, /*<! TX_HEADER */
GUI_REG_TX_DATA = 0x54, /*<! TX_DATA */
GUI_REG_VBUS_VOLTAGE = 0x70, /*<! VBUS_VOLTAGE */
GUI_REG_VBUS_SINK_DISCONNECT_THRESHOLD = 0x72, /*<! VBUS_SINK_DISCONNECT_THRESHOLD */
GUI_REG_VBUS_STOP_DISCHARGE_THRESHOLD = 0x74, /*<! VBUS_STOP_DISCHARGE_THRESHOLD */
GUI_REG_VBUS_VOLTAGE_ALARM_HI_CFG = 0x76, /*<! VBUS_VOLTAGE_ALARM_HI_CFG */
GUI_REG_VBUS_VOLTAGE_ALARM_LO_CFG = 0x78, /*<! VBUS_VOLTAGE_ALARM_LO_CFG */
GUI_REG_VENDOR_DATA = 0x80, /*<! VENDOR_DATA */
} USBPD_GUI_RegisterTCPC;
/**
* @brief USB PD GUI TAG PARAM
*/
typedef enum
{
GUI_PARAM_SOP = 0x00, /*<! SOP support */
GUI_PARAM_SOP1 = 0x00, /*<! SOP prime support */
GUI_PARAM_SOP2 = 0x00, /*<! SOP second support */
GUI_PARAM_FASTROLESWAP = 0x02, /*<! It enables the FRS */
GUI_PARAM_DATAROLESWAP_TO_UFP = 0x03, /*<! Support of Data role swap to UFP */
GUI_PARAM_DEFAULTPOWERROLE = 0x04, /*<! DRP on PE side but no toggle on CAD (dependency with CADRoleToggle) */
GUI_PARAM_DRP_SUPPORT = 0x05, /*<! DRP support (Power Role swap support) */
GUI_PARAM_CADROLETOGGLE = 0x06, /*<! CAD Role Toggle */
GUI_PARAM_PE_SCAP_HR = 0x07, /*<! Hard reset after N_SOURCE_CAPS message sending tentatives */
GUI_PARAM_VCONNSWAP = 0x08, /*<! It enables or disables the VCONN swap capability */
GUI_PARAM_VDM_SUPPORT = 0x09, /*<! Indicate if VDM messages support is enabled or not */
GUI_PARAM_PING_SUPPORT = 0x0A, /*<! Indicate if Ping message support is enabled or not */
GUI_PARAM_PPS_SUPPORT = 0x0B, /*<! PPS message supported by PE */
GUI_PARAM_SRCCAPAEXTSUPPORT = 0x0B, /*<! Source_Capabilities_Extended message supported by PE */
GUI_PARAM_ALERTSUPPORT = 0x0B, /*<! Alert message supported by PE */
GUI_PARAM_STATUSSUPPORT = 0x0B, /*<! Status message supported by PE (Is_Alert_Supported should be enabled) */
GUI_PARAM_BATTERYSTATUSSUPPORT = 0x0B, /*<! Battery_Status message supported by PE */
GUI_PARAM_BATTERYCAPASUPPORT = 0x0B, /*<! Battery_Capabilities message supported by PE */
GUI_PARAM_MANUINFOSUPPORT = 0x0B, /*<! Manufacturer_Info message supported by PE */
GUI_PARAM_COUNTRYCODESSUPPORT = 0x0B, /*<! Country_Codes message supported by PE */
GUI_PARAM_COUNTRYINFOSUPPORT = 0x0B, /*<! Country_Info message supported by PE */
GUI_PARAM_SECURESPONSESUPPORT = 0x0B, /*<! Security_Response message supported by PE */
GUI_PARAM_SNK_PDO = 0x0C, /*<! maximum 7 * 32bit */
GUI_PARAM_SRC_PDO = 0x0D, /*<! maximum 7 * 32bit */
GUI_PARAM_TDRP = 0x0E, /*<! The period a DRP shall complete a Source to Sink and back advertisement */
GUI_PARAM_DCSRC_DRP = 0x0F, /*<! The percent of time that a DRP shall advertise Source during tDRP (in %) */
GUI_PARAM_RESPONDS_TO_DISCOV_SOP = 0x10, /*<! UUT can respond successfully to a Discover Identity command from its port partner using SOP. */
GUI_PARAM_ATTEMPTS_DISCOV_SOP = 0x11, /*<! UUT can send a Discover Identity command to its port partner using SOP */
GUI_PARAM_XID_SOP = 0x12, /*<! A decimal number assigned by USB-IF before certification */
GUI_PARAM_DATA_CAPABLE_AS_USB_HOST_SOP = 0x13, /*<! Indicates whether the UUT is capable of enumerating USB Host */
GUI_PARAM_DATA_CAPABLE_AS_USB_DEVICE_SOP = 0x14, /*<! Indicates whether the UUT is capable of enumerating as a USB Device */
GUI_PARAM_PRODUCT_TYPE_SOP = 0x15, /*<! What is the product type of the UUT? */
GUI_PARAM_MODAL_OPERATION_SUPPORTED_SOP = 0x16, /*<! Does the product support Modes? */
GUI_PARAM_USB_VID_SOP = 0x17, /*<! A unique 16-bit number, assigned to the Vendor by USB-IF. */
GUI_PARAM_PID_SOP = 0x18, /*<! A unique number assigned by the Vendor ID holder identifying the product */
GUI_PARAM_BCDDEVICE_SOP = 0x19, /*<! A unique number assigned by the Vendor ID holder containing identity information relevant to the release version of the product. */
GUI_PARAM_MEASUREREPORTING = 0x1A, /*<! 0x00: Disable Measure reporting
(1 << 8) | (tr between 0 & 127): Enable Measure reporting every tr x 40 ms (if xx = 0 means only 1 indication to report to GUI) */
GUI_PARAM_MANUINFOPORT_VID = 0x1B, /*<! Vendor ID (assigned by the USB-IF)) used by Manufacturer info set for port */
GUI_PARAM_MANUINFOPORT_PID = 0x1B, /*<! Product ID (assigned by the manufacturer) used by Manufacturer info set for port */
GUI_PARAM_MANUINFOPORT_STRING = 0x1B, /*<! Vendor string used by Manufacturer info set for port */
GUI_PARAM_DATAROLESWAP_TO_DFP = 0x1C, /*<! Support of Data role swap to DFP */
GUI_PARAM_NB_TAG = (GUI_PARAM_DATAROLESWAP_TO_DFP + 1), /*<! Number max of param */
GUI_PARAM_ALL = 0xFFu,
} USBPD_GUI_Tag_Param;
/**
* @brief USB PD GUI TAG INDICATION
*/
typedef enum
{
GUI_IND_NUMBEROFRCVSNKPDO = 0x00, /*<! The number of received Sink Power Data Objects from port Partner (when Port partner is a Sink or a DRP port) */
GUI_IND_RDOPOSITION = 0x01, /*<! RDO Position of requested DO in Source list of capabilities */
GUI_IND_LISTOFRCVSRCPDO = 0x02, /*<! The list of received Source Power Data Objects from Port partner (when Port partner is a Source or a DRP port) */
GUI_IND_NUMBEROFRCVSRCPDO = 0x03, /*<! The number of received Source Power Data Objects from port Partner (when Port partner is a Source or a DRP port) */
GUI_IND_LISTOFRCVSNKPDO = 0x04, /*<! The list of received Sink Power Data Objects from Port partner (when Port partner is a Sink or a DRP port) */
GUI_IND_ISCONNECTED = 0x05, /*<! USB PD connection state */
GUI_IND_CC = 0x06, /*<! CC side */
GUI_IND_DATAROLE = 0x07, /*<! It defines the initial data role. */
GUI_IND_POWERROLE = 0x08, /*<! It defines the power role. */
GUI_IND_CCDEFAULTCURRENTADVERTISED = 0x09, /*<! advertising the current capability */
GUI_IND_VCONNON = 0x0A, /*<! Vconn Status */
GUI_IND_VBUS_LEVEL = 0x0C, /*<! VBUS level (in mV) */
GUI_IND_IBUS_LEVEL = 0x0C, /*<! IBUS level (in mA) */
GUI_IND_PD_SPECREVISION = 0x0D, /*<! Selected Specification revision */
GUI_IND_PD_MESSAGENOTIF = 0x0E, /*<! Send notifications of PD messages */
GUI_IND_NBBATTERIES = 0x0F, /*<! Number of batteries supported by the devices. */
GUI_IND_COUNTRYCODES = 0x10, /*<! List of the country codes received in the COUNTRY_CODES message */
GUI_IND_SVDM_SVIDS = 0x11, /*<! List of the SVDM SVID received in the SVDM Discovery SVID message */
GUI_IND_SVDM_MODES = 0x12, /*<! List of the country codes received in the SVDM Discovery SVID message */
GUI_IND_TIMESTAMP = 0x13, /*<! Timestamp used for VBUS and IBUS values */
GUI_IND_PPS = 0x14, /*<! PPS value based on @ref USBPD_PPSSDB_TypeDef */
GUI_IND_STATUS = 0x15, /*<! Status value based on @ref USBPD_SDB_TypeDef */
GUI_IND_VDM_IDENTITY = 0x16, /*<! VDM Identity based on @ref USBPD_IDHeaderVDO_TypeDef */
GUI_IND_CABLE_VDO = 0x19, /*<! VDM Cable Object based on @ref USBPD_CableVdo_TypeDef */
GUI_IND_ALL = (GUI_IND_CABLE_VDO + 1), /*<! Number max of indication */
} USBPD_GUI_Tag_Indication;
/**
* @brief USB PD GUI TAG PARAM_MSG
*/
typedef enum
{
GUI_PARAM_MSG_SOPTYPE = 0x00, /*<! SOP type used for DPM_MESSAGE_REQ */
GUI_PARAM_MSG_RDOPOSITION = 0x01, /*<! RDO position of Received SRC PDO (used for RESET_REQ) */
GUI_PARAM_MSG_REQUESTEDVOLTAGE = 0x02, /*<! Requested voltage in REQUEST message (in mV) */
GUI_PARAM_MSG_ALERTMSG = 0x04, /*<! Alert message used in ALERT message */
GUI_PARAM_MSG_COUNTRYCODE = 0x05, /*<! Coutry code used in GET_COUNTRY_INFO message */
GUI_PARAM_MSG_SVDM_SVID = 0x06, /*<! SVID used in SVDM disco mode, enter mode & exit mode */
GUI_PARAM_MSG_SVDM_MODEINDEX = 0x07, /*<! Mode index used in SVDM enter and exit mode messages */
GUI_PARAM_MSG_UVDM_DATA = 0x08, /*<! Data used in UVDM message */
GUI_PARAM_MSG_DP_STATUS = 0x09, /*<! Data used in DP status message */
GUI_PARAM_MSG_DP_CONFIGURE = 0x0A, /*<! Data used in DP config message */
GUI_PARAM_MSG_DP_ATTENTION = 0x0B, /*<! Data used in DP attention message */
GUI_PARAM_MSG_BATTERYREF = 0x0C, /*<! Battery reference used in Get battery capa & status message */
GUI_PARAM_MSG_MANUINFODATA = 0x0D, /*<! Manufacturer_Info data used in Get Manufacturer info message */
GUI_PARAM_MSG_FREE_TEXT = 0x0E, /*<! Free text */
GUI_PARAM_MSG_ALL = (GUI_PARAM_MSG_FREE_TEXT + 1), /*<! Number max of msg param */
} USBPD_GUI_Tag_ParamMsg;
/**
* @brief USB PD GUI MESSAGES
*/
typedef enum
{
GUI_MSG_GOTOMIN = 0x00, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_PING = 0x01, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_GET_SRC_CAPA = 0x03, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_GET_SNK_CAPA = 0x04, /*<! Message sent only if port partner is DRP. Answer to this message is a SNK_CAPA
Note: Refer to Control message in USB_PD specv3.0
*/
GUI_MSG_DR_SWAP = 0x05, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_PR_SWAP = 0x06, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_VCONN_SWAP = 0x07, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_SOFT_RESET = 0x08, /*<! Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_GET_SOURCE_CAPA_EXTENDED = 0x09, /*<! Specific to PD3.0
Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_GET_STATUS = 0x0A, /*<! Specific to PD3.0. Return a STATUS message
Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_FR_SWAP = 0x0B, /*<! Specific to PD3.0
Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_GET_PPS_STATUS = 0x0C, /*<! Specific to PD3.0. Wait for PPS_STATUS message
Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_GET_COUNTRY_CODES = 0x0D, /*<! Specific to PD3.0. Return a COUNTRY_CODES message
Note: Refer to Control message in USB_PD specv3.0 */
GUI_MSG_SOURCE_CAPA = 0x0E, /*<! DPM_CONFIG_SET_REQ to be sent before sending this message
Note: Refer to data message in USB_PD specv3.0 */
GUI_MSG_REQUEST = 0x0F, /*<! Select one of the capability available.
Note: Refer to data message in USB_PD specv3.0 */
GUI_MSG_ALERT = 0x11, /*<! Specific to PD3.0
Note: Refer to data message in USB_PD specv3.0 */
GUI_MSG_GET_COUNTRY_INFO = 0x12, /*<! Return COUNTRY_INFO message.
Note: Refer to data message in USB_PD specv3.0 */
GUI_MSG_VDM_DISCO_IDENT = 0x13, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_VDM_DISCO_SVID = 0x14, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_VDM_DISCO_MODE = 0x15, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_VDM_ENTER_MODE = 0x16, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_VDM_EXIT_MODE = 0x17, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_VDM_ATTENTION = 0x18, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_VDM_UNSTRUCTURED = 0x19, /*<! 1..7 x 32bit
Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_FREE_TEXT = 0x1A, /*<! Free text */
GUI_MSG_DISPLAY_PORT_STATUS = 0x20, /*<! 1..7 x 32bit
Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_DISPLAY_PORT_CONFIG = 0x21, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_DISPLAY_PORT_ATTENTION = 0x22, /*<! Note: Refer to VDM message in USB_PD specv3.0 */
GUI_MSG_HARD_RESET = 0x24, /*<! Note: refer to Reset messages in USB_PD specv3.0 */
GUI_MSG_CABLE_RESET = 0x25, /*<! Note: refer to Reset messages in USB_PD specv3.0 */
GUI_MSG_GET_BAT_CAPA = 0x26, /*<! Return BAT_CAPA message
Note: Refer to extended message in USB_PD specv3.0 */
GUI_MSG_GET_BAT_STATUS = 0x27, /*<! Return BAT_STATUS message
Note: Refer to extended message in USB_PD specv3.0 */
GUI_MSG_GET_MANU_INFO = 0x28, /*<! Return MANU_INFO message
Note: Refer to extended message in USB_PD specv3.0 */
GUI_MSG_SECU_REQUEST = 0x29, /*<! Note: Refer to extended message in USB_PD specv3.0 */
GUI_MSG_FIRM_UPDATE_REQUEST = 0x2A, /*<! Note: Refer to extended message in USB_PD specv3.0 */
GUI_MSG_GET_SINK_CAPA_EXTENDED = 0x2B, /*<! Specific to PD3.0
Note: Refer to Control message in USB_PD specv3.0 */
} USBPD_GUI_Messages;
/**
* @brief USB PD GUI INIT
*/
typedef enum
{
GUI_INIT_HWBOARDVERSION = 0x00, /*<! ASCII stream to indicate STM32 version like STM32F032xB */
GUI_INIT_HWPDTYPE = 0x01, /*<! ASCII stream to indicate PD type used by the devices like:
- AFE solution (MB1257B)
- 1602 solution (MB1303 rev A)
- TCPM solution (TCPC FUSB305)
- () */
GUI_INIT_NBPORTMAX = 0x02, /*<! Indicate maximum number of ports which can be configured in the device (value 1, 2 , 3) */
GUI_INIT_FWVERSION = 0x03, /*<! 4 bytes for FW version + 4 bytes for Stack version */
GUI_INIT_TYPECSPECREVISION = 0x04, /*<! Type-C revision supported by the port */
GUI_INIT_PDSPECREVISION = 0x04, /*<! PD spec revision supported by the port */
GUI_INIT_EXTENDEDMESSAGESUNCKUNKED = 0x06, /*<! Supports extended messages */
GUI_INIT_ACCESSORYSUPP = 0x07, /*<! Accessory supported or not */
GUI_INIT_POWERACCESSORYDETECTION = 0x08, /*<! It enables or disables powered accessory detection */
GUI_INIT_POWERACCESSORYTRANSITION = 0x09, /*<! It enables or disables transition from Powered.accessory to Try.SNK */
GUI_INIT_ISCABLE = 0x0B, /*<! Cable (asserts Ra on VConn, communicates using SOP' and SOP''), when this mode is selected the stack will run in cable mode so all parameters like PowerRole are not used */
GUI_INIT_TRYFEATURE = 0x10, /*<! Try Feature */
GUI_INIT_RPRESISTORVALUE = 0x12, /*<! RP resistor value */
GUI_INIT_USBSUPPORT = 0x13, /*<! USB_Comms_Capable, is the UUT capable of enumerating as a USB host or device? */
GUI_INIT_USBDEVICE = 0x14, /*<! Type_C_Can_Act_As_Device, Indicates whether the UUT can communicate with USB 2.0 or USB 3.1 as a device or as the Upstream Facing Port of a hub. */
GUI_INIT_USBHOST = 0x15, /*<! Type_C_Can_Act_As_Host, Indicates whether the UUT can communicate with USB 2.0 or USB 3.1 as a host or as the Downstream Facing Port of a hub */
GUI_INIT_UNCONSTRAINED_POWERED = 0x16, /*<! UUT has an external power source available that is sufficient to adequately power the system while charging external devices or the UUTs primary function is to charge external devices. */
GUI_INIT_USBSUSPENDSUPPORT = 0x17, /*<! USB Suspend support */
GUI_INIT_VCONNDISCHARGE = 0x18, /*<! It enables or disables the VCONN discharge on CC pin */
GUI_INIT_VCONNILIM = 0x19, /*<! enables or not VconnLim */
GUI_INIT_VCONNILIMVALUE = 0x1A, /*<! It allows changing the default current limit supplying VCONN on the CC pins */
GUI_INIT_VCONNMONITORING = 0x1B, /*<! It enables or disables UVLO threshold detection on VCONN pin */
GUI_INIT_VCONNTHRESHOLDUVLO = 0x1C, /*<! High UVLO threshold of 4.65 V; 1b: Low UVLO threshold of 2.65 V (case of VCONN-powered accessories operating down to 2.7 V) */
GUI_INIT_VCONNSUPPLY = 0x1D, /*<! It enables or disables the VCONN supply capability on CC pin */
GUI_INIT_NB_PORT_START = 0x1E, /*<! Start Port number */
GUI_INIT_ORIGINAL_SETTINGS = 0x1F, /*<! This flag allows to know if the user settings read by the FW are from the original FW or a previous configuration saved by the user. */
} USBPD_GUI_Init;
typedef enum {
GUI_USER_EVENT_TIMER, /* TIMER EVENT */
GUI_USER_EVENT_GUI, /* GUI EVENT */
GUI_USER_EVENT_NONE, /* NO EVENT */
} GUI_USER_EVENT;
/**
* @brief USBPD DPM handle Structure definition
* @{
*/
typedef struct
{
uint32_t ListOfRcvSRCPDO[USBPD_MAX_NB_PDO]; /*!< The list of received Source Power Data Objects from Port partner
(when Port partner is a Source or a DRP port). */
uint32_t NumberOfRcvSRCPDO; /*!< The number of received Source Power Data Objects from port Partner
(when Port partner is a Source or a DRP port).
This parameter must be set to a value lower than USBPD_MAX_NB_PDO */
uint32_t ListOfRcvSNKPDO[USBPD_MAX_NB_PDO]; /*!< The list of received Sink Power Data Objects from Port partner
(when Port partner is a Sink or a DRP port). */
uint32_t NumberOfRcvSNKPDO; /*!< The number of received Sink Power Data Objects from port Partner
(when Port partner is a Sink or a DRP port).
This parameter must be set to a value lower than USBPD_MAX_NB_PDO */
uint32_t RDOPosition; /*!< RDO Position of requested DO in Source list of capabilities */
uint32_t RequestedVoltage; /*!< Value of requested voltage */
uint32_t RequestedCurrent; /*!< Value of requested current */
uint32_t RDOPositionPrevious; /*!< RDO Position of previous requested DO in Source list of capabilities */
uint32_t RcvRequestDOMsg; /*!< Received request Power Data Object message from the port Partner */
#if defined(USBPD_REV30_SUPPORT)
#if _STATUS
USBPD_SDB_TypeDef RcvStatus; /*!< Status received by port partner */
#endif /* _STATUS */
#if _PPS
USBPD_PPSSDB_TypeDef RcvPPSStatus; /*!< PPS Status received by port partner */
#endif /* _PPS */
#if _SRC_CAPA_EXT
USBPD_SCEDB_TypeDef RcvSRCExtendedCapa; /*!< SRC Extended Capability received by port partner */
#endif /* _SRC_CAPA_EXT */
#if defined(USBPDCORE_SNK_CAPA_EXT)
USBPD_SKEDB_TypeDef RcvSNKExtendedCapa; /*!< SNK Extended Capability received by port partner */
#endif /* USBPDCORE_SNK_CAPA_EXT */
#if _MANU_INFO
USBPD_GMIDB_TypeDef GetManufacturerInfo; /*!< Get Manufacturer Info */
#endif /* _MANU_INFO */
#if _BATTERY
USBPD_GBSDB_TypeDef GetBatteryStatus; /*!< Get Battery status */
USBPD_GBCDB_TypeDef GetBatteryCapability; /*!< Get Battery Capability */
USBPD_BSDO_TypeDef BatteryStatus; /*!< Battery status */
#endif /* _BATTERY */
USBPD_ADO_TypeDef RcvAlert; /*!< Save the Alert received by port partner */
#endif /* USBPD_REV30_SUPPORT */
#ifdef _VCONN_SUPPORT
USBPD_DiscoveryIdentity_TypeDef VDM_DiscoCableIdentify; /*!< VDM Cable Discovery Identify */
#endif /* _VCONN_SUPPORT */
#ifdef _VDM
USBPD_DiscoveryIdentity_TypeDef VDM_DiscoIdentify; /*!< VDM Discovery Identify */
USBPD_SVIDPortPartnerInfo_TypeDef VDM_SVIDPortPartner; /*!< VDM SVID list */
USBPD_ModeInfo_TypeDef VDM_ModesPortPartner; /*!< VDM Modes list */
#endif /* _VDM */
} GUI_HandleTypeDef;
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/** @defgroup USBPD_GUI_API_Private_Macros USBPD GUI API Private Macros
* @{
*/
#define __GUI_SET_TAG_ID(_PORT_, _TAG_) ((_PORT_) << GUI_PORT_BIT_POSITION | (_TAG_))
#if defined(_RTOS)
#if (osCMSIS < 0x20000U)
#define GUI_START_TIMER(_PORT_,_TIMER_,_TIMEOUT_) do{ \
_TIMER_[_PORT_] = (_TIMEOUT_) | GUI_TIMER_ENABLE_MSK; \
osMessagePut(GUIMsgBox,GUI_USER_EVENT_TIMER, 0); \
}while(0);
#else
#define GUI_START_TIMER(_PORT_,_TIMER_,_TIMEOUT_) do{ \
uint32_t event = GUI_USER_EVENT_TIMER; \
_TIMER_[_PORT_] = (_TIMEOUT_) | GUI_TIMER_ENABLE_MSK; \
(void)osMessageQueuePut(GUIMsgBox, &event, 0U, 0U); \
}while(0);
#endif /* osCMSIS < 0x20000U */
#else
#define GUI_START_TIMER(_PORT_, _TIMER_,_TIMEOUT_) _TIMER_[_PORT_] = (_TIMEOUT_) | GUI_TIMER_ENABLE_MSK;
#endif /* _RTOS */
#define IS_GUI_TIMER_RUNNING(_PORT_, _TIMER_) ((_TIMER_[_PORT_] & GUI_TIMER_READ_MSK) > 0)
#define IS_GUI_TIMER_EXPIRED(_PORT_, _TIMER_) (GUI_TIMER_ENABLE_MSK == _TIMER_[_PORT_])
#if defined(_SNK) || defined(_DRP)
#define GUI_UPDATE_VOLTAGE_MIN(_PDO_VOLT_, _SNK_VOLT_) \
if ((_PDO_VOLT_) < (_SNK_VOLT_)) \
{ \
/* Update min voltage */ \
(_SNK_VOLT_) = (_PDO_VOLT_); \
}
#define GUI_UPDATE_VOLTAGE_MAX(_PDO_VOLT_, _SNK_VOLT_) \
if ((_PDO_VOLT_) > (_SNK_VOLT_)) \
{ \
/* Update min voltage */ \
(_SNK_VOLT_) = (_PDO_VOLT_); \
}
#define GUI_UPDATE_CURRENT_MAX(_PDO_CURRENT_, _SNK_CURRENT_) \
if ((_PDO_CURRENT_) > (_SNK_CURRENT_)) \
{ \
/* Update min current */ \
(_SNK_CURRENT_) = (_PDO_CURRENT_); \
}
#define GUI_UPDATE_POWER_MAX(_PDO_POWER_, _SNK_POWER_) \
if ((_PDO_POWER_) > (_SNK_POWER_)) \
{ \
/* Update min POWER */ \
(_SNK_POWER_) = (_PDO_POWER_); \
}
#define GUI_CHECK_VOLTAGE_MIN(_PDO_VOLT_, _SNK_VOLT_) \
/* Update min voltage */ \
(_SNK_VOLT_) = (_PDO_VOLT_);
#define GUI_CHECK_VOLTAGE_MAX(_PDO_VOLT_, _SNK_VOLT_) \
/* Update min voltage */ \
(_SNK_VOLT_) = (_PDO_VOLT_);
#define GUI_CHECK_CURRENT_MAX(_PDO_CURRENT_, _SNK_CURRENT_) \
/* Update min current */ \
(_SNK_CURRENT_) = (_PDO_CURRENT_);
#define GUI_CHECK_POWER_MAX(_PDO_POWER_, _SNK_POWER_) \
/* Update min POWER */ \
(_SNK_POWER_) = (_PDO_POWER_);
#define GUI_DECODE_50MV(_Value_) ((uint16_t)(((_Value_) * 50))) /* From 50mV multiples to mV */
#define GUI_DECODE_100MV(_Value_) ((uint16_t)(((_Value_) * 100))) /* From 100mV multiples to mV */
#define GUI_DECODE_10MA(_Value_) ((uint16_t)(((_Value_) * 10))) /* From 10mA multiples to mA */
#define GUI_DECODE_50MA(_Value_) ((uint16_t)(((_Value_) * 50))) /* From 50mA multiples to mA */
#define GUI_DECODE_MW(_Value_) ((uint16_t)(((_Value_) * 250))) /* From 250mW multiples to mW */
#endif /* _SNK) || _DRP */
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/** @defgroup USBPD_GUI_API_Private_Variables USBPD GUI API Private Variables
* @{
*/
volatile uint16_t GUI_TimerMeasReport[USBPD_PORT_COUNT]; /*!< Timer used to send measurement report */
extern USBPD_SettingsTypeDef DPM_Settings[USBPD_PORT_COUNT];
#ifdef _VDM
extern USBPD_VDM_SettingsTypeDef DPM_VDM_Settings[USBPD_PORT_COUNT];
#endif /* _VDM */
GUI_USER_ParamsTypeDef GUI_USER_Params[USBPD_PORT_COUNT];
uint8_t PtrDataRx[TLV_SIZE_MAX];
uint8_t Processed[TLV_SIZE_MAX];
USBPD_GUI_State GUI_State = GUI_STATE_INIT;
/*!< Flag to indicate that user settings is from original FW (not saved into the FLASH) */
uint8_t GUI_OriginalSettings;
#if defined(_RTOS)
osMessageQId GUIMsgBox;
#if (osCMSIS >= 0x20000U)
osThreadAttr_t GUI_Thread_Atrr = {
.name = "GUI",
.priority = FREERTOS_GUI_PRIORITY, /*osPriorityLow,*/
.stack_size = FREERTOS_GUI_STACK_SIZE
};
#endif /* osCMSIS >= 0x20000U */
#else
volatile uint32_t GUI_Flag = GUI_USER_EVENT_NONE;
#endif /* _RTOS */
const uint8_t* (*pCB_HWBoardVersion)(void) = NULL;
const uint8_t* (*pCB_HWPDType)(void) = NULL;
uint16_t (*pCB_GetVoltage)(uint8_t) = NULL;
int16_t (*pCB_GetCurrent)(uint8_t) = NULL;
USBPD_StatusTypeDef (*pCB_FreeText)(uint8_t, uint8_t*, uint16_t) = NULL;
GUI_HandleTypeDef GUI_SaveInformation[USBPD_PORT_COUNT];
/**
* @}
*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup USBPD_GUI_API_Private_Functions GUI API Private Functions
* @{
*/
#ifdef _RTOS
#if (osCMSIS < 0x20000U)
static void TaskGUI(void const *argument);
#else
static void TaskGUI(void *argument);
#endif /* osCMSIS < 0x20000U */
static uint32_t CheckGUITimers(void);
#endif /* _RTOS */
static void GUI_CALLBACK_RX(uint8_t Character, uint8_t Error);
static void Send_DpmInitCnf(uint8_t PortNum, uint8_t *string);
static void Request_MessageReq(uint8_t PortNum, uint8_t* instruction, uint8_t *pEncodedMsg);
static void Send_DpmConfigSetCnf(uint8_t PortNum, uint8_t* instruction, uint8_t *pEncodedMsg);
static void Send_DpmConfigGetCnf(uint8_t PortNum, uint8_t* instruction, uint8_t *pEncodedMsg);
static void Send_DpmConfigGetRej(uint8_t PortNum, uint8_t *pEncodedMsg, USBPD_GUI_Reject_Reason RejecReason);
static void Send_DpmMessageRej(uint8_t PortNum, uint8_t *pEncodedMsg, USBPD_GUI_Reject_Reason RejecReason);
static void Send_DpmRegisterReadCnf(uint8_t PortNum, uint8_t *string, uint8_t param);
static void Send_DpmRegisterWriteCnf(uint8_t PortNum, uint8_t *string, uint8_t *toProcess);
static USBPD_StatusTypeDef Manage_FreeText(uint8_t PortNum, uint8_t *pPayload, uint16_t Size);
#if defined(_SNK) || defined(_DRP)
static void UpdateSNKPowerPort0(void);
#if USBPD_PORT_COUNT==2
static void UpdateSNKPowerPort1(void);
#endif /* USBPD_PORT_COUNT==2 */
#endif /* _SNK) || _DRP */
#if defined(USE_STM32_UTILITY_OS)
void GUI_Execute(void);
#endif /* USE_STM32_UTILITY_OS */
/**
* @}
*/
/* Exported functions ------------------------------------------------------- */
/** @addtogroup USBPD_GUI_API_Exported_Functions
* @{
*/
/**
* @brief GUI initialization function
* @param CB_HWBoardVersion BSP callback to retrieve HW Board version
* @param CB_HWPDType BSP callback to retrieve HW PD Type
* @param CB_GetVoltage BSP callback to retrieve VBUS voltage
* @param CB_GetCurrent BSP callback to retrieve IBUS current
* @retval Functional state
*/
USBPD_FunctionalState GUI_Init(const uint8_t* (*CB_HWBoardVersion)(void), const uint8_t* (*CB_HWPDType)(void), uint16_t (*CB_GetVoltage)(uint8_t), int16_t (*CB_GetCurrent)(uint8_t))
{
USBPD_FunctionalState _status = USBPD_ENABLE;
/* Retrieve data from FLASH if needed */
GUI_OriginalSettings = ((GUI_OK == BSP_GUI_LoadDataFromFlash()) ? USBPD_FALSE : USBPD_TRUE);
/* Need to update CAD_tDRP & CAD_dcSRC_DRP if CAD_SNKToggleTime not initialized */
if ((0U == DPM_Settings[USBPD_PORT_0].CAD_SNKToggleTime) || (0U == DPM_Settings[USBPD_PORT_0].CAD_SRCToggleTime))
{
DPM_USER_Settings[USBPD_PORT_0].CAD_tDRP = 80U;
DPM_USER_Settings[USBPD_PORT_0].CAD_dcSRC_DRP = 50U;
}
else
{
DPM_USER_Settings[USBPD_PORT_0].CAD_dcSRC_DRP = (DPM_Settings[USBPD_PORT_0].CAD_SRCToggleTime * 100) / (DPM_Settings[USBPD_PORT_0].CAD_SRCToggleTime + DPM_Settings[USBPD_PORT_0].CAD_SNKToggleTime);
DPM_USER_Settings[USBPD_PORT_0].CAD_tDRP = (DPM_Settings[USBPD_PORT_0].CAD_SRCToggleTime * 100) / DPM_USER_Settings[USBPD_PORT_0].CAD_dcSRC_DRP;
}
#if USBPD_PORT_COUNT==2
if ((0U == DPM_Settings[USBPD_PORT_1].CAD_SNKToggleTime) || (0U == DPM_Settings[USBPD_PORT_1].CAD_SRCToggleTime))
{
DPM_USER_Settings[USBPD_PORT_1].CAD_tDRP = 80U;
DPM_USER_Settings[USBPD_PORT_1].CAD_dcSRC_DRP = 50U;
}
else
{
DPM_USER_Settings[USBPD_PORT_1].CAD_dcSRC_DRP = (DPM_Settings[USBPD_PORT_1].CAD_SRCToggleTime * 100) / (DPM_Settings[USBPD_PORT_1].CAD_SRCToggleTime + DPM_Settings[USBPD_PORT_1].CAD_SNKToggleTime);
DPM_USER_Settings[USBPD_PORT_1].CAD_tDRP = (DPM_Settings[USBPD_PORT_1].CAD_SRCToggleTime * 100) / DPM_USER_Settings[USBPD_PORT_1].CAD_dcSRC_DRP;
}
#endif /* USBPD_PORT_COUNT==2 */
pCB_HWBoardVersion = CB_HWBoardVersion;
pCB_HWPDType = CB_HWPDType;
pCB_GetVoltage = CB_GetVoltage;
pCB_GetCurrent = CB_GetCurrent;
/* Register 2 callbacks for notification in DPM */
USBPD_DPM_SetNotification_GUI(GUI_FormatAndSendNotification, GUI_PostNotificationMessage, GUI_SaveInfo);
#if defined(_RTOS)
#if (osCMSIS < 0x20000U)
osMessageQDef(MsgBox, GUI_BOX_MESSAGES_MAX, uint32_t);
osThreadDef(GUI, TaskGUI, FREERTOS_GUI_PRIORITY, 0, FREERTOS_GUI_STACK_SIZE);
GUIMsgBox = osMessageCreate(osMessageQ(MsgBox), NULL);
if(NULL == osThreadCreate(osThread(GUI), &GUIMsgBox))
#else
GUIMsgBox = osMessageQueueNew (GUI_BOX_MESSAGES_MAX, sizeof(uint32_t), NULL);
if (NULL == osThreadNew(TaskGUI, &GUIMsgBox, &GUI_Thread_Atrr))
#endif /* osCMSIS < 0x20000U */
{
_status = USBPD_DISABLE;
}
/* Enable IRQ which has been disabled by FreeRTOS services */
__enable_irq();
#else /* RTOS */
GUI_Start();
#if defined(USE_STM32_UTILITY_OS)
UTIL_SEQ_RegTask(TASK_GUI, 0, GUI_Execute);
UTIL_SEQ_SetTask(TASK_GUI, 0);
#endif /*USE_STM32_UTILITY_OS */
#endif /* _RTOS */
return _status;
}
void GUI_Start(void)
{
/* register the GUI callback to manage UART reception */
TRACER_EMB_StartRX(GUI_CALLBACK_RX);
}
/**
* @brief GUI Task
* @param pEvent GUI User event
* @retval None
*/
#ifdef _RTOS
#if (osCMSIS < 0x20000U)
static void TaskGUI(void const *pEvent)
#else
static void TaskGUI(void *pEvent)
#endif /* osCMSIS < 0x20000U */
#else
void GUI_Execute(void)
#endif /* _RTOS */
{
#ifdef _RTOS
uint32_t _timing = osWaitForever;
osMessageQId queue = *(osMessageQId *)pEvent;
GUI_Start();
do
{
#if (osCMSIS < 0x20000U)
osEvent event = osMessageGet(queue, _timing);
switch (((GUI_USER_EVENT)event.value.v & 0xF))
#else
uint32_t event;
(void)osMessageQueueGet(queue, &event, NULL, _timing);
switch (((GUI_USER_EVENT)event & 0xF))
#endif /* osCMSIS < 0x20000U */
{
case GUI_USER_EVENT_GUI:
{
#if (osCMSIS < 0x20000U)
GUI_RXProcess((uint32_t)event.value.v);
#else
GUI_RXProcess((uint32_t)event);
#endif /* osCMSIS < 0x20000U */
/* Sent an event to check if measurement report has been requested */
#if (osCMSIS < 0x20000U)
osMessagePut(GUIMsgBox, GUI_USER_EVENT_TIMER, 0);
#else
uint32_t event = GUI_USER_EVENT_TIMER;
(void)osMessageQueuePut(GUIMsgBox, &event, 0U, 0U);
#endif /* osCMSIS < 0x20000U */
break;
}
case GUI_USER_EVENT_TIMER:
{
#endif /* _RTOS */
#ifndef _RTOS
switch (GUI_Flag & 0xF)
{
case GUI_USER_EVENT_NONE:
break;
case GUI_USER_EVENT_GUI:
GUI_RXProcess(GUI_Flag);
case GUI_USER_EVENT_TIMER:
break;
default:
break;
}
GUI_Flag = GUI_USER_EVENT_NONE;
#endif /* !_RTOS */
for(uint8_t _instance = 0; _instance < USBPD_PORT_COUNT; _instance++)
{
/* ------------------------------------------------- */
/* Check if timeout related to Measurement reporting */
/* ------------------------------------------------- */
/* - Send a GUI Event only if PE is connected
and Measurement report has been enabled */
if ((USBPD_TRUE == DPM_Params[_instance].PE_IsConnected)
&& (1 == GUI_USER_Params[_instance].u.d.MeasReportActivation)
&& (0 != GUI_USER_Params[_instance].u.d.MeasReportValue))
{
/* Check if timer has expired */
if (IS_GUI_TIMER_EXPIRED(_instance, GUI_TimerMeasReport))
{
uint32_t event_mr = GUI_USER_EVENT_GUI | (_instance << GUI_PE_PORT_NUM_Pos) | (GUI_NOTIF_MEASUREMENT << GUI_PE_NOTIF_Pos);
GUI_RXProcess(event_mr);
}
/* Start or Restart Measurement report timer */
if (!(IS_GUI_TIMER_RUNNING(_instance, GUI_TimerMeasReport)))
{
GUI_START_TIMER(_instance, GUI_TimerMeasReport, (GUI_USER_Params[_instance].u.d.MeasReportValue * GUI_NOTIF_MEASUREMENT_STEP));
}
}
else
{
/* Stop measurement report timer */
GUI_TimerMeasReport[_instance] = 0;
}
}
#ifdef _RTOS
break;
}
default:
break;
}
_timing = CheckGUITimers();
}
while(1);
#endif /* !_RTOS */
}
#ifdef _RTOS
static uint32_t CheckGUITimers(void)
{
uint32_t _timing = osWaitForever;
uint32_t _current_timing;
/* Calculate the minimum timers to wake-up GUI task */
for(uint8_t instance = 0; instance < USBPD_PORT_COUNT; instance++)
{
/* Check if Measurement reporting has been enabled by the GUI */
_current_timing = GUI_TimerMeasReport[instance] & GUI_TIMER_READ_MSK;
if(_current_timing > 0)
{
if (_current_timing < _timing)
{
_timing = _current_timing;
}
}
}
return _timing;
}
#endif /* !_RTOS */
void GUI_TimerCounter(void)
{
/* Increment GUI timer only if Measurement report has been activated */
if (1 == GUI_USER_Params[USBPD_PORT_0].u.d.MeasReportActivation)
{
if((GUI_TimerMeasReport[USBPD_PORT_0] & GUI_TIMER_READ_MSK) > 0)
{
GUI_TimerMeasReport[USBPD_PORT_0]--;
}
#if !defined(_RTOS)&&defined(USE_STM32_UTILITY_OS)
else
{
UTIL_SEQ_SetTask(TASK_GUI, 0);
}
#endif /* !_RTOS && USE_STM32_UTILITY_OS */
}
#if USBPD_PORT_COUNT==2
if (1 == GUI_USER_Params[USBPD_PORT_1].u.d.MeasReportActivation)
{
if((GUI_TimerMeasReport[USBPD_PORT_1] & GUI_TIMER_READ_MSK) > 0)
{
GUI_TimerMeasReport[USBPD_PORT_1]--;
}
#if !defined(_RTOS)&&defined(USE_STM32_UTILITY_OS)
else
{
UTIL_SEQ_SetTask(TASK_GUI, 0);
}
#endif /* !_RTOS && USE_STM32_UTILITY_OS */
}
#endif /* USBPD_PORT_COUNT == 2 */
}
/**
* @brief callback called to end a transfer.
* @param Character Byte received by the device
* @param Error Error detected in the reception
* @retval 1 if message to send to DPM application
*/
void GUI_CALLBACK_RX(uint8_t Character, uint8_t Error)
{
uint32_t event;
__disable_irq();
event = GUI_GetMessage(Character, Error);
__enable_irq();
if (event == 1)
{
#if defined(_RTOS)
#if (osCMSIS < 0x20000U)
(void)osMessagePut(GUIMsgBox, GUI_USER_EVENT_GUI, 1);
#else
uint32_t event = GUI_USER_EVENT_GUI;
(void)osMessageQueuePut(GUIMsgBox, &event, 0U, 0U);
#endif /* osCMSIS < 0x20000U */
#else
GUI_Flag = GUI_USER_EVENT_GUI;
#if defined(USE_STM32_UTILITY_OS)
GUI_RXProcess(GUI_Flag);
GUI_Flag = GUI_USER_EVENT_NONE;
#endif /* USE_STM32_UTILITY_OS */
#endif /* _RTOS */
}
}
/**
* @brief Main Trace RX process to push data on the media.
* @param Event GUI trace event
* @retval Timing
*/
uint32_t GUI_RXProcess(uint32_t Event)
{
uint8_t *msg;
USBPD_GUI_State state;
uint8_t size;
if (0 == (Event & GUI_PE_NOTIF_Msk))
{
/* Message have been received by GUI */
state = GUI_SendAnswer(&msg, &size);
switch (state)
{
case GUI_STATE_RESET:
/* DPM_RESET_REQ received by the device */
/* Save parameters in FLASH */
BSP_GUI_SaveDataInFlash();
HAL_NVIC_SystemReset();
break;
case GUI_STATE_INIT:
/* DPM_INIT_REQ received by the device */
break;
default:
/* Another GUI messages received by the device */
TRACER_EMB_Add(msg, size);
break;
}
}
else
{
uint16_t type_event = (Event & GUI_PE_NOTIF_Msk) >> GUI_PE_NOTIF_Pos;
if (GUI_NOTIF_MEASUREMENT == type_event)
{
/* Notification related to timeout for measure reporting */
/* Send a notification to associated port */
GUI_FormatAndSendNotification(((Event & GUI_PE_PORT_NUM_Msk) >> GUI_PE_PORT_NUM_Pos), GUI_NOTIF_MEASUREREPORTING, HAL_GetTick());
}
else
{
/* Message have been received by PE */
/* Send a notification to associated port */
GUI_FormatAndSendNotification(((Event & GUI_PE_PORT_NUM_Msk) >> GUI_PE_PORT_NUM_Pos), GUI_NOTIF_PE_EVENT, type_event);
}
}
return 0;
}
/**
* @brief TRACE function to send a notification
* @param PortNum Index of current used port
* @param TypeNotification Type of requested notification is a combination of @ref USBPD_TRACE_TRACE_TYPE_NOTIFICATION
* @param Value Value depending of TypeNotification
* @note If TypeNotification == GUI_NOTIF_ISCONNECTED, Value should be equal to 0 (Not connected) or 1 (connected)
* @retval USBPD Status
*/
uint32_t GUI_FormatAndSendNotification(uint32_t PortNum, uint32_t TypeNotification, uint32_t Value)
{
uint8_t *msg;
uint8_t size;
/* Only send notification if GUI is connected */
if (GUI_STATE_INIT != GUI_SendNotification(PortNum, &msg, &size, TypeNotification, Value))
{
TRACER_EMB_Add(msg, size);
}
return 0;
}
/**
* @brief Function called through UART IT RX to fill the GUI RX buffer
* @param Character Received byte
* @param Error Error if issue during reception
* @retval 1 indicates that a complete GUI message have been received
*/
uint32_t GUI_GetMessage(uint8_t Character, uint8_t Error)
{
uint32_t status = 0;
static uint16_t counter = 0; /* Allows for example to count the number of SOF or EOF we received consecutively */
static uint16_t cursor = 0; /* Our position in the buffer */
static uint16_t currentSize; /* How many bytes we should expect */
static enum receptionStateMachine
{
Rstart,
RonGoing,
Rsize,
Rend,
Rerror
} Rstate = Rstart;
if(cursor < TLV_SIZE_MAX)
{
PtrDataRx[cursor] = Character;
}
else /* buffer too small, overflow */
{
cursor = 0;
counter = 0;
Rstate = Rstart;
return 0;
}
if(Error) Rstate = Rerror;
switch(Rstate)
{
case Rstart :
if(PtrDataRx[cursor] == TLV_SOF)
{
counter++;
}
else
{
counter = 0;
cursor = 0xFFFF; /* cursor is unsigned, but it will inevitably increments at the end of function, and we need a 0 at the next pass here */
}
if(counter == 4) /* The whole SOF is received */
{
counter = 0;
Rstate = Rsize;
}
break;
case Rsize :
counter++;
if(counter == 3) /* We have received the size */
{
currentSize = (PtrDataRx[cursor-1] << 8) + PtrDataRx[cursor];
if (0 == currentSize)
{
Rstate = Rend;
}
else
{
Rstate = RonGoing;
}
counter = 0;
}
break;
case RonGoing :
counter++;
if(counter == currentSize)
{
/* When there is no value, the first EOF is handled by Rongoing, before Rend takes control */
counter = 0;
Rstate = Rend;
}
break;
case Rend :
counter++;
if(PtrDataRx[cursor] == TLV_EOF
&& PtrDataRx[cursor-1] == TLV_EOF
&& PtrDataRx[cursor-2] == TLV_EOF
&& PtrDataRx[cursor-3] == TLV_EOF)
{
/* The semaphore must be given only in this case, because otherwise it means we didn't receive the correct size of bytes */
if(counter == 4)
{
status = 1;
}
counter = 0;
cursor = 0xFFFF;
Rstate = Rstart;
}
if(cursor == currentSize + 11)
{
/* No complete EOF arrived. We reset the buffer for safety even if the instruction might be complete. */
counter = 0;
cursor = 0xFFFF;
Rstate = Rstart;
}
break;
case Rerror :
counter = 0;
cursor = 0xFFFF;
Rstate = Rstart;
break;
}
cursor++;
return status;
}
/**
* @brief Answer to a message received by the GUI
* @param pMsgToSend Pointer on the message to send
* @param pSizeMsg Pointer on the size of the message to send
* @retval GUI state
*/
USBPD_GUI_State GUI_SendAnswer(uint8_t **pMsgToSend, uint8_t *pSizeMsg)
{
/* Extract the port from the tag*/
uint8_t port = PtrDataRx[TLV_TAG_POSITION] >> GUI_PORT_BIT_POSITION;
/* Do the appropriate treatment in response to what we have received */
switch(PtrDataRx[TLV_TAG_POSITION] & 0x1F)
{
case DPM_RESET_REQ:
/* Reset*/
return GUI_STATE_RESET;
case DPM_INIT_REQ:
{
Send_DpmInitCnf(port, Processed);
*pMsgToSend = Processed;
*pSizeMsg = TLV_get_string_length(Processed) + 8;
TRACER_EMB_Add(*pMsgToSend, *pSizeMsg);
GUI_State = GUI_STATE_RUNNING;
if (0 == port)
{
/* Send a notification all the port */
GUI_FormatAndSendNotification(USBPD_PORT_0, GUI_NOTIF_ISCONNECTED | GUI_NOTIF_PE_EVENT | GUI_NOTIF_TIMESTAMP, USBPD_NOTIFY_ALL);
#if USBPD_PORT_COUNT==2
GUI_FormatAndSendNotification(USBPD_PORT_1, GUI_NOTIF_ISCONNECTED | GUI_NOTIF_PE_EVENT | GUI_NOTIF_TIMESTAMP, USBPD_NOTIFY_ALL);
#endif /* USBPD_PORT_COUNT == 2 */
}
return GUI_STATE_INIT;
}
case DPM_CONFIG_GET_REQ:
if (0 != port)
{
Send_DpmConfigGetCnf((port - 1), PtrDataRx, Processed);
}
else
{
Send_DpmConfigGetRej(port, Processed, GUI_REJ_DPM_INVALID_PORT_NUMBER);
}
break;
case DPM_CONFIG_SET_REQ:
if (0 != port)
{
Send_DpmConfigSetCnf((port - 1), PtrDataRx, Processed);
}
else
{
Send_DpmConfigGetRej(port, Processed, GUI_REJ_DPM_INVALID_PORT_NUMBER);
}
break;
case DPM_MESSAGE_REQ:
if (0 != port)
{
Request_MessageReq((port - 1), PtrDataRx, Processed);
}
else
{
Send_DpmMessageRej(port, Processed, GUI_REJ_DPM_INVALID_PORT_NUMBER);
}
break;
case DPM_REGISTER_READ_REQ:
if (0 != port)
{
/* If size is 0*/
if(!PtrDataRx[TLV_LENGTH_HIGH_POSITION] && !PtrDataRx[TLV_LENGTH_LOW_POSITION])
{
Send_DpmRegisterReadCnf((port - 1), Processed, 0xFF);
}
else
{
/* PtrDataRx[TLV_VALUE_POSITION] is the tag in parameter,
when only one parameter is needed (cf USBPD GUI specification)*/
Send_DpmRegisterReadCnf((port - 1), Processed, PtrDataRx[TLV_VALUE_POSITION]);
}
}
else
{
Send_DpmConfigGetRej(port, Processed, GUI_REJ_DPM_INVALID_PORT_NUMBER);
}
break;
case DPM_REGISTER_WRITE_REQ:
if (0 != port)
{
Send_DpmRegisterWriteCnf((port - 1), Processed, PtrDataRx);
}
else
{
Send_DpmConfigGetRej(port, Processed, GUI_REJ_DPM_INVALID_PORT_NUMBER);
}
break;
default :
break;
}
*pMsgToSend = Processed;
*pSizeMsg = TLV_get_string_length(Processed) + 8;
return GUI_State;
}
/**
* @brief Answer to a message received by the GUI
* @param PortNum Port number
* @param pMsgToSend Pointer on the message to send
* @param pSizeMsg Pointer on the size of the message to send
* @param TypeNotification Type of the notification
* @param Value Value of the notification
* @retval GUI state
*/
USBPD_GUI_State GUI_SendNotification(uint8_t PortNum, uint8_t **pMsgToSend, uint8_t *pSizeMsg, uint32_t TypeNotification, uint32_t Value)
{
TLV_ToSend_Data send_tlv;
USBPD_GUI_State gui_state = GUI_STATE_INIT;
/* Send a notitification only if GUI is running */
if (GUI_State == GUI_STATE_RUNNING)
{
TLV_init_encode(&send_tlv, __GUI_SET_TAG_ID((PortNum + 1), DPM_MESSAGE_IND), TLV_SIZE_MAX, Processed);
/* Check PD connection */
if ((TypeNotification & GUI_NOTIF_ISCONNECTED) == GUI_NOTIF_ISCONNECTED)
{
/* Is Connected*/
TLV_add(&send_tlv, GUI_IND_ISCONNECTED, 1, (uint8_t[]){DPM_Params[PortNum].PE_Power});
if (USBPD_TRUE == DPM_Params[PortNum].PE_IsConnected)
{
uint8_t rp_value = 0;
/* CC line */
TLV_add(&send_tlv, GUI_IND_CC, 1, (uint8_t[]){DPM_Params[PortNum].ActiveCCIs});
/* Power Role*/
TLV_add(&send_tlv, GUI_IND_POWERROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_PowerRole});
/* CC Default Current Advertised */
rp_value = 3; /* (uint8_t)CAD_GetRPValue(PortNum); */
TLV_add(&send_tlv, GUI_IND_CCDEFAULTCURRENTADVERTISED, 1, &rp_value);
if (USBPD_POWER_EXPLICITCONTRACT == DPM_Params[PortNum].PE_Power)
{
/* Data Role*/
TLV_add(&send_tlv, GUI_IND_DATAROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_DataRole});
/* Vconn ON*/
TLV_add(&send_tlv, GUI_IND_VCONNON, 1, (uint8_t[]){DPM_Params[PortNum].VconnStatus});
/* PD_Spec Revision */
TLV_add(&send_tlv, GUI_IND_PD_SPECREVISION, 1, (uint8_t[]){DPM_Params[PortNum].PE_SpecRevision});
}
}
}
/* Check PD message event */
if ((TypeNotification & GUI_NOTIF_PE_EVENT) == GUI_NOTIF_PE_EVENT)
{
if (USBPD_NOTIFY_ALL != Value)
{
/* PD_MessageNotif */
TLV_add(&send_tlv, GUI_IND_PD_MESSAGENOTIF, 1, (uint8_t*)&Value);
switch (Value)
{
case USBPD_NOTIFY_POWER_STATE_CHANGE :
/* Is Connected*/
TLV_add(&send_tlv, GUI_IND_ISCONNECTED, 1, (uint8_t[]){DPM_Params[PortNum].PE_Power});
if (USBPD_POWER_NO == DPM_Params[PortNum].PE_Power)
{
/* CC line */
TLV_add(&send_tlv, GUI_IND_CC, 1, (uint8_t[]){DPM_Params[PortNum].ActiveCCIs});
/* PowerRole*/
TLV_add(&send_tlv, GUI_IND_POWERROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_PowerRole});
}
break;
case USBPD_NOTIFY_GETSNKCAP_ACCEPTED :
/* NumberOfRcvSNKPDO */
TLV_add(&send_tlv, GUI_IND_NUMBEROFRCVSNKPDO, 1, (uint8_t[]){GUI_SaveInformation[PortNum].NumberOfRcvSNKPDO});
/* ListOfRcvSNKPDO*/
TLV_add(&send_tlv, GUI_IND_LISTOFRCVSNKPDO, GUI_SaveInformation[PortNum].NumberOfRcvSNKPDO * 4, (uint8_t *) GUI_SaveInformation[PortNum].ListOfRcvSNKPDO);
break;
case USBPD_NOTIFY_GETSRCCAP_ACCEPTED :
/* NumberOfRcvSRCPDO*/
TLV_add(&send_tlv, GUI_IND_NUMBEROFRCVSRCPDO, 1, (uint8_t[]){GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO});
/* ListOfRcvSRCPDO*/
TLV_add(&send_tlv, GUI_IND_LISTOFRCVSRCPDO, GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO * 4, (uint8_t *) GUI_SaveInformation[PortNum].ListOfRcvSRCPDO);
break;
case USBPD_NOTIFY_POWER_EXPLICIT_CONTRACT :
if (USBPD_PORTPOWERROLE_SNK == DPM_Params[PortNum].PE_PowerRole)
{
/* NumberOfRcvSRCPDO*/
TLV_add(&send_tlv, GUI_IND_NUMBEROFRCVSRCPDO, 1, (uint8_t[]){GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO});
/* ListOfRcvSRCPDO*/
TLV_add(&send_tlv, GUI_IND_LISTOFRCVSRCPDO, GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO * 4, (uint8_t *) GUI_SaveInformation[PortNum].ListOfRcvSRCPDO);
}
/* RDOPosition */
TLV_add(&send_tlv, GUI_IND_RDOPOSITION, 1, (uint8_t[]){GUI_SaveInformation[PortNum].RDOPosition});
/* DataRole*/
TLV_add(&send_tlv, GUI_IND_DATAROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_DataRole});
/* PowerRole*/
TLV_add(&send_tlv, GUI_IND_POWERROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_PowerRole});
/* VconnON*/
TLV_add(&send_tlv, GUI_IND_VCONNON, 1, (uint8_t[]){DPM_Params[PortNum].VconnStatus});
/* PD_SpecRevision */
TLV_add(&send_tlv, GUI_IND_PD_SPECREVISION, 1, (uint8_t[]){DPM_Params[PortNum].PE_SpecRevision});
break;
case USBPD_NOTIFY_POWER_SWAP_TO_SNK_DONE :
case USBPD_NOTIFY_POWER_SWAP_TO_SRC_DONE :
/* PowerRole*/
TLV_add(&send_tlv, GUI_IND_POWERROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_PowerRole});
break;
case USBPD_NOTIFY_DATAROLESWAP_UFP :
case USBPD_NOTIFY_DATAROLESWAP_DFP :
/* DataRole*/
TLV_add(&send_tlv, GUI_IND_DATAROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_DataRole});
break;
case USBPD_NOTIFY_PD_SPECIFICATION_CHANGE :
/* PD_SpecRevision */
TLV_add(&send_tlv, GUI_IND_PD_SPECREVISION, 1, (uint8_t[]){DPM_Params[PortNum].PE_SpecRevision});
break;
case USBPD_NOTIFY_VCONN_SWAP_COMPLETE :
/* VconnON */
TLV_add(&send_tlv, GUI_IND_VCONNON, 1, (uint8_t[]){DPM_Params[PortNum].VconnStatus});
break;
#if _PPS
case USBPD_NOTIFY_PPS_STATUS_RECEIVED :
/* PPS value */
TLV_add(&send_tlv, GUI_IND_PPS, 4, (uint8_t*)&GUI_SaveInformation[PortNum].RcvPPSStatus.d32);
break;
#endif /* _PPS */
#if _STATUS
case USBPD_NOTIFY_STATUS_RECEIVED :
{
uint8_t tab[5] = {
GUI_SaveInformation[PortNum].RcvStatus.InternalTemp,
GUI_SaveInformation[PortNum].RcvStatus.PresentInput,
GUI_SaveInformation[PortNum].RcvStatus.PresentBatteryInput,
GUI_SaveInformation[PortNum].RcvStatus.EventFlags,
GUI_SaveInformation[PortNum].RcvStatus.TemperatureStatus
};
/* Status value */
TLV_add(&send_tlv, GUI_IND_STATUS, 5, tab);
}
break;
#endif /* _STATUS */
#ifdef _VDM
case USBPD_NOTIFY_VDM_IDENTIFY_RECEIVED :
TLV_add(&send_tlv, GUI_IND_VDM_IDENTITY, 4, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_DiscoIdentify.IDHeader.d32);
break;
case USBPD_NOTIFY_VDM_SVID_RECEIVED :
{
uint32_t index;
uint16_t size;
/* List of received SVDM SVID */
if (0 != GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.NumSVIDs)
{
TLV_add(&send_tlv, GUI_IND_SVDM_SVIDS, 2, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.SVIDs[0]);
size = 2;
for (index = 1; index < GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.NumSVIDs; index++)
{
TLV_addValue(&send_tlv, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.SVIDs[index], 2);
size += 2;
}
TLV_UpdateSizeTag(&send_tlv, size);
}
}
break;
case USBPD_NOTIFY_VDM_MODE_RECEIVED :
{
uint32_t index;
uint16_t size;
/* List of received SVDM MODES */
if (0 != GUI_SaveInformation[PortNum].VDM_ModesPortPartner.NumModes)
{
TLV_add(&send_tlv, GUI_IND_SVDM_MODES, 4, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_ModesPortPartner.Modes[0]);
size = 4;
for (index = 1; index < GUI_SaveInformation[PortNum].VDM_ModesPortPartner.NumModes; index++)
{
TLV_addValue(&send_tlv, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_ModesPortPartner.Modes[index], 4);
size += 4;
}
TLV_UpdateSizeTag(&send_tlv, size);
}
}
break;
#endif /* _VDM */
#if defined(_VCONN_SUPPORT)
case USBPD_NOTIFY_VDM_CABLE_IDENT_RECEIVED :
TLV_add(&send_tlv, GUI_IND_CABLE_VDO, 4, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_DiscoCableIdentify.CableVDO.d32);
break;
#endif /* _VCONN_SUPPORT */
}
}
else
{
/* Send all the indication parameters if connected */
if (USBPD_TRUE == DPM_Params[PortNum].PE_IsConnected)
{
#if defined(_VDM)
uint32_t index;
#endif /* _VDM */
if (0 != GUI_SaveInformation[PortNum].NumberOfRcvSNKPDO)
{
/* NumberOfRcvSNKPDO */
TLV_add(&send_tlv, GUI_IND_NUMBEROFRCVSNKPDO, 1, (uint8_t[]){GUI_SaveInformation[PortNum].NumberOfRcvSNKPDO});
/* ListOfRcvSNKPDO*/
TLV_add(&send_tlv, GUI_IND_LISTOFRCVSNKPDO, GUI_SaveInformation[PortNum].NumberOfRcvSNKPDO * 4, (uint8_t *) GUI_SaveInformation[PortNum].ListOfRcvSNKPDO);
}
/* RDOPosition */
TLV_add(&send_tlv, GUI_IND_RDOPOSITION, 1, (uint8_t[]){GUI_SaveInformation[PortNum].RDOPosition});
if (USBPD_PORTPOWERROLE_SNK == DPM_Params[PortNum].PE_PowerRole)
{
/* NumberOfRcvSRCPDO*/
TLV_add(&send_tlv, GUI_IND_NUMBEROFRCVSRCPDO, 1, (uint8_t[]){GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO});
/* ListOfRcvSRCPDO*/
TLV_add(&send_tlv, GUI_IND_LISTOFRCVSRCPDO, GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO * 4, (uint8_t *) GUI_SaveInformation[PortNum].ListOfRcvSRCPDO);
}
/* PD_SpecRevision */
TLV_add(&send_tlv, GUI_IND_PD_SPECREVISION, 1, (uint8_t[]){DPM_Params[PortNum].PE_SpecRevision});
#if defined(USBPD_REV30_SUPPORT)
#if _SRC_CAPA_EXT
/* Number of batteries supported by the port partner */
TLV_add(&send_tlv, GUI_IND_NBBATTERIES, 1, (uint8_t[]){GUI_SaveInformation[PortNum].RcvSRCExtendedCapa.NbBatteries});
#endif /* _SRC_CAPA_EXT */
#endif /* USBPD_REV30_SUPPORT */
#if defined(_VDM)
if (0 != GUI_SaveInformation[PortNum].VDM_DiscoIdentify.IDHeader.d32)
{
TLV_add(&send_tlv, GUI_IND_VDM_IDENTITY, 4, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_DiscoIdentify.IDHeader.d32);
}
#if defined(_VCONN_SUPPORT)
if (1 == GUI_SaveInformation[PortNum].VDM_DiscoCableIdentify.CableVDO_Presence)
{
TLV_add(&send_tlv, GUI_IND_CABLE_VDO, 4, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_DiscoCableIdentify.CableVDO.d32);
}
#endif /* _VCONN_SUPPORT */
/* List of received SVDM SVID */
if (0 != GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.NumSVIDs)
{
uint16_t size;
TLV_add(&send_tlv, GUI_IND_SVDM_SVIDS, 2, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.SVIDs[0]);
size = 2;
for (index = 1; index < GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.NumSVIDs; index++)
{
TLV_addValue(&send_tlv, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_SVIDPortPartner.SVIDs[index], 2);
size += 2;
}
TLV_UpdateSizeTag(&send_tlv, size);
}
/* List of received SVDM MODES */
if (0 != GUI_SaveInformation[PortNum].VDM_ModesPortPartner.NumModes)
{
uint16_t size;
TLV_add(&send_tlv, GUI_IND_SVDM_MODES, 4, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_ModesPortPartner.Modes[0]);
size = 4;
for (index = 1; index < GUI_SaveInformation[PortNum].VDM_ModesPortPartner.NumModes; index++)
{
TLV_addValue(&send_tlv, (uint8_t*)&GUI_SaveInformation[PortNum].VDM_ModesPortPartner.Modes[index], 4);
size += 4;
}
TLV_UpdateSizeTag(&send_tlv, size);
}
#endif /* _VDM */
}
}
}
/* Check if notification linked to a measure report */
if ((TypeNotification & GUI_NOTIF_MEASUREREPORTING) == GUI_NOTIF_MEASUREREPORTING)
{
uint32_t vsense = 0;
int32_t isense = 0;
TLV_add(&send_tlv, GUI_IND_TIMESTAMP, 4, (uint8_t*)&Value);
if (NULL != pCB_GetVoltage)
{
vsense = pCB_GetVoltage(PortNum);
}
if (NULL != pCB_GetVoltage)
{
isense = pCB_GetCurrent(PortNum);
if(isense < 0)
{
isense = -isense;
}
}
/* VBUS & IBUS level */
vsense = (isense << 16) | vsense;
TLV_add(&send_tlv, GUI_IND_VBUS_LEVEL, 4, (uint8_t*)&vsense);
}
/* Check if timestamp */
if ((TypeNotification & GUI_NOTIF_TIMESTAMP) == GUI_NOTIF_TIMESTAMP)
{
TLV_add(&send_tlv, GUI_IND_TIMESTAMP, 4, (uint8_t*)&Value);
}
/* Check if power change */
if ((TypeNotification & GUI_NOTIF_POWER_EVENT) == GUI_NOTIF_POWER_EVENT)
{
/* Is Connected*/
TLV_add(&send_tlv, GUI_IND_ISCONNECTED, 1, (uint8_t[]){DPM_Params[PortNum].PE_Power});
if (USBPD_POWER_NO == DPM_Params[PortNum].PE_Power)
{
/* CC line */
TLV_add(&send_tlv, GUI_IND_CC, 1, (uint8_t[]){DPM_Params[PortNum].ActiveCCIs});
/* PowerRole*/
TLV_add(&send_tlv, GUI_IND_POWERROLE, 1, (uint8_t[]){DPM_Params[PortNum].PE_PowerRole});
}
}
TLV_deinit_encode(&send_tlv);
if (0 != TLV_get_string_length(Processed))
{
*pMsgToSend = Processed;
*pSizeMsg = TLV_get_string_length(Processed) + 8;
gui_state = GUI_STATE_RUNNING;
}
}
return gui_state;
}
/**
* @brief Callback function called by PE to inform GUI about PE event.
* @param PortNum Port number
* @param EventVal Event vale @ref USBPD_NotifyEventValue_TypeDef
* @retval None
*/
void GUI_PostNotificationMessage(uint8_t PortNum, uint16_t EventVal)
{
#if defined(_SNK) || defined(_DRP)
if (USBPD_NOTIFY_REQUEST_ACCEPTED == EventVal)
{
DPM_USER_Settings[PortNum].DPM_SNKRequestedPower.OperatingVoltageInmVunits = GUI_SaveInformation[PortNum].RequestedVoltage;
DPM_USER_Settings[PortNum].DPM_SNKRequestedPower.OperatingPowerInmWunits = (GUI_SaveInformation[PortNum].RequestedVoltage * GUI_SaveInformation[PortNum].RequestedCurrent) / 1000;
}
#endif /* _SNK || _DRP */
/* Send a notitification only if GUI is running */
if (GUI_State == GUI_STATE_RUNNING)
{
uint32_t event = GUI_USER_EVENT_GUI | (PortNum << GUI_PE_PORT_NUM_Pos) | (EventVal << GUI_PE_NOTIF_Pos);
#if defined(_RTOS)
#if (osCMSIS < 0x20000U)
(void)osMessagePut(GUIMsgBox, event, 0);
#else
(void)osMessageQueuePut(GUIMsgBox, &event, 0U, 0U);
#endif /* osCMSIS < 0x20000U */
#else
GUI_Flag = event;
#if defined(USE_STM32_UTILITY_OS)
GUI_RXProcess(GUI_Flag);
GUI_Flag = GUI_USER_EVENT_NONE;
#endif /* USE_STM32_UTILITY_OS */
#endif /* _RTOS */
}
}
/**
* @brief Check is GUI is connected to the board or not
* @retval USBPD state
*/
USBPD_FunctionalState GUI_IsRunning(void)
{
return ((GUI_State == GUI_STATE_RUNNING) ? USBPD_ENABLE : USBPD_DISABLE);
}
/**
* @brief GUI callback to save information coming from PortPartner
* @param PortNum Port number
* @param DataId Type of data to be updated in DPM based on @ref USBPD_CORE_DataInfoType_TypeDef
* @param Ptr Pointer on the data
* @param Size Nb of bytes to be updated in GUI
* @retval None
*/
void GUI_SaveInfo(uint8_t PortNum, uint8_t DataId, uint8_t *Ptr, uint32_t Size)
{
uint32_t index;
/* Check type of information targeted by request */
switch (DataId)
{
/* Case requested DO position Data information :
*/
case USBPD_CORE_DATATYPE_RDO_POSITION :
if (Size == 4)
{
uint8_t* temp;
temp = (uint8_t*)&GUI_SaveInformation[PortNum].RDOPosition;
(void)memcpy(temp, Ptr, Size);
GUI_SaveInformation[PortNum].RDOPositionPrevious = *Ptr;
temp = (uint8_t*)&GUI_SaveInformation[PortNum].RDOPositionPrevious;
(void)memcpy(temp, Ptr, Size);
}
break;
/* Case Received Source PDO values Data information :
*/
case USBPD_CORE_DATATYPE_RCV_SRC_PDO :
if (Size <= (USBPD_MAX_NB_PDO * 4))
{
uint8_t* rdo;
GUI_SaveInformation[PortNum].NumberOfRcvSRCPDO = (Size / 4);
/* Copy PDO data in DPM Handle field */
for (index = 0; index < (Size / 4); index++)
{
rdo = (uint8_t*)&GUI_SaveInformation[PortNum].ListOfRcvSRCPDO[index];
(void)memcpy(rdo, (Ptr + (index * 4u)), (4u * sizeof(uint8_t)));
}
}
break;
/* Case Received Sink PDO values Data information :
*/
case USBPD_CORE_DATATYPE_RCV_SNK_PDO :
if (Size <= (USBPD_MAX_NB_PDO * 4))
{
uint8_t* rdo;
GUI_SaveInformation[PortNum].NumberOfRcvSNKPDO = (Size / 4);
/* Copy PDO data in DPM Handle field */
for (index = 0; index < (Size / 4); index++)
{
rdo = (uint8_t*)&GUI_SaveInformation[PortNum].ListOfRcvSNKPDO[index];
(void)memcpy(rdo, (Ptr + (index * 4u)), (4u * sizeof(uint8_t)));
}
}
break;
/* Case Received Request PDO Data information :
*/
case USBPD_CORE_DATATYPE_RCV_REQ_PDO :
if (Size == 4)
{
uint8_t* rdo;
rdo = (uint8_t*)&GUI_SaveInformation[PortNum].RcvRequestDOMsg;
(void)memcpy(rdo, Ptr, Size);
}
break;
#if defined(USBPD_REV30_SUPPORT)
#if _STATUS
case USBPD_CORE_INFO_STATUS :
{
uint8_t* info_status;
info_status = (uint8_t*)&GUI_SaveInformation[PortNum].RcvStatus;
memcpy(info_status, Ptr, Size);
}
break;
#endif /* _STATUS */
#if _PPS
case USBPD_CORE_PPS_STATUS :
{
uint8_t* ext_capa;
ext_capa = (uint8_t*)&GUI_SaveInformation[PortNum].RcvPPSStatus;
memcpy(ext_capa, Ptr, Size);
}
break;
#endif /* _PPS */
#if _SRC_CAPA_EXT
case USBPD_CORE_EXTENDED_CAPA :
{
uint8_t* ext_capa;
ext_capa = (uint8_t*)&GUI_SaveInformation[PortNum].RcvSRCExtendedCapa;
memcpy(ext_capa, Ptr, Size);
}
break;
#endif /* _SRC_CAPA_EXT */
#if defined(USBPDCORE_SNK_CAPA_EXT)
case USBPD_CORE_SNK_EXTENDED_CAPA :
{
uint8_t* _snk_ext_capa;
_snk_ext_capa = (uint8_t*)&GUI_SaveInformation[PortNum].RcvSNKExtendedCapa;
memcpy(_snk_ext_capa, Ptr, Size);
}
break;
#endif /* USBPDCORE_SNK_CAPA_EXT */
#if _MANU_INFO
case USBPD_CORE_GET_MANUFACTURER_INFO:
{
uint8_t* temp = (uint8_t*)Ptr;
GUI_SaveInformation[PortNum].GetManufacturerInfo.ManufacturerInfoTarget = *temp;
GUI_SaveInformation[PortNum].GetManufacturerInfo.ManufacturerInfoRef = *(temp + 1);
}
break;
#endif /* _MANU_INFO */
#if _BATTERY
case USBPD_CORE_BATTERY_STATUS:
GUI_SaveInformation[PortNum].BatteryStatus.d32 = *Ptr;
break;
case USBPD_CORE_GET_BATTERY_STATUS:
{
GUI_SaveInformation[PortNum].GetBatteryStatus.BatteryStatusRef = *(uint8_t*)Ptr;
}
break;
case USBPD_CORE_GET_BATTERY_CAPABILITY:
{
uint8_t* temp = (uint8_t*)Ptr;
GUI_SaveInformation[PortNum].GetBatteryCapability.BatteryCapRef= *temp;
}
break;
#endif /* _BATTERY */
#if _ALERT
case USBPD_CORE_ALERT:
{
uint8_t* alert;
alert = (uint8_t*)&GUI_SaveInformation[PortNum].RcvAlert.d32;
memcpy(alert, Ptr, Size);
}
break;
#endif /* _ALERT */
#endif /* USBPD_REV30_SUPPORT */
#if defined(_VCONN_SUPPORT)
case GUI_VDM_CABLE_INFO:
{
uint8_t* disco_ident;
disco_ident = (uint8_t*)&GUI_SaveInformation[PortNum].VDM_DiscoCableIdentify;
memcpy(disco_ident, Ptr, Size);
}
break;
#endif /* _VCONN_SUPPORT */
/* In case of unexpected data type (Set request could not be fulfilled) :
*/
default :
break;
}
}
/**
* @brief Register callback function to be used with Free Text feature
* @param CB_FreeText Callback function to register (port number, payload and size)
* @retval None
*/
void GUI_RegisterCallback_FreeText(USBPD_StatusTypeDef (*CB_FreeText)(uint8_t, uint8_t*, uint16_t))
{
pCB_FreeText = CB_FreeText;
}
/**
* @}
*/
/** @defgroup USBPD_GUI_API_Private_Functions GUI API Private Functions
* @{
*/
/**
* @brief Send DPM_INIT_CNF message to GUI
* @param PortNum Port number
* @param pEncodedMsg Pointer on the message to be encoded
* @retval None
*/
static void Send_DpmInitCnf(uint8_t PortNum, uint8_t *pEncodedMsg)
{
TLV_ToSend_Data ToSendTLV;
TLV_init_encode(&ToSendTLV, __GUI_SET_TAG_ID(PortNum, DPM_INIT_CNF), TLV_SIZE_MAX, pEncodedMsg);
/* Information by board */
if (0 == PortNum)
{
/* HWBoardVersion */
const uint8_t* hwversion;
if (NULL != pCB_HWBoardVersion)
{
hwversion = pCB_HWBoardVersion();
}
else
{
hwversion = (uint8_t*) "UNKNOWN";
}
TLV_add(&ToSendTLV, GUI_INIT_HWBOARDVERSION, strlen((const char*)hwversion), hwversion);
/* HWPDType */
const uint8_t* hwpdtype;
if (NULL != pCB_HWBoardVersion)
{
hwpdtype = pCB_HWPDType();
}
else
{
hwpdtype = (uint8_t*) "UNKNOWN";
}
TLV_add(&ToSendTLV, GUI_INIT_HWPDTYPE, strlen((const char*)hwpdtype), hwpdtype);
/* NbPortMax */
TLV_add(&ToSendTLV, GUI_INIT_NBPORTMAX, 1, (uint8_t[]){USBPD_PORT_COUNT});
/* FW Version */
TLV_add(&ToSendTLV, GUI_INIT_FWVERSION, 8, (uint8_t[]){
(USBPD_FW_VERSION & 0x000000FF),
(USBPD_FW_VERSION & 0x0000FF00) >> 8,
(USBPD_FW_VERSION & 0x00FF0000) >> 16,
(USBPD_FW_VERSION & 0xFF000000) >> 24,
(_LIB_ID & 0x000000FF),
(_LIB_ID & 0x0000FF00) >> 8,
(_LIB_ID & 0x00FF0000) >> 16,
(_LIB_ID & 0xFF000000) >> 24}
);
/* Start Port number */
TLV_add(&ToSendTLV, GUI_INIT_NB_PORT_START, 1, (uint8_t[]){USBPD_START_PORT_NUMBER});
/* Start Port number */
TLV_add(&ToSendTLV, GUI_INIT_NB_PORT_START, 1, (uint8_t[]){USBPD_START_PORT_NUMBER});
/* Original settings */
TLV_add(&ToSendTLV, GUI_INIT_ORIGINAL_SETTINGS, 1, (uint8_t*)&GUI_OriginalSettings);
TLV_deinit_encode(&ToSendTLV);
}
else
{
uint16_t settings;
uint8_t port = PortNum - 1;
#if defined(MB1303)
uint16_t fake = 0xADDE;
#endif /*MB1303*/
/* TypeCSpecVersion & PDSpecRevision */
settings = DPM_Settings[port].PE_SpecRevision;
TLV_add(&ToSendTLV, GUI_INIT_TYPECSPECREVISION, 2, (uint8_t[]){0x12, settings});
#if defined(USBPD_REV30_SUPPORT)
/* Extended Messages UnCkunked */
settings = DPM_Settings[port].PE_PD3_Support.d.PE_UnchunkSupport;
TLV_add(&ToSendTLV, GUI_INIT_EXTENDEDMESSAGESUNCKUNKED, 1, (uint8_t*)&settings);
#endif /* USBPD_REV30_SUPPORT */
/* AccessorySupp */
settings = DPM_Settings[port].CAD_AccesorySupport;
TLV_add(&ToSendTLV, GUI_INIT_ACCESSORYSUPP, 1, (uint8_t*)&settings);
/*PowerAccessoryDetection*/
settings = DPM_USER_Settings[port].PWR_AccessoryDetection;
TLV_add(&ToSendTLV, GUI_INIT_POWERACCESSORYDETECTION, 1, (uint8_t*)&settings);
/*PowerAccessoryTransition*/
settings = DPM_USER_Settings[port].PWR_AccessoryTransition;
TLV_add(&ToSendTLV, GUI_INIT_POWERACCESSORYTRANSITION, 1, (uint8_t*)&settings);
/*IsCable*/
TLV_add(&ToSendTLV, GUI_INIT_ISCABLE, 1, (uint8_t[]){0x00});
/*TryFeature*/
settings = DPM_Settings[port].CAD_TryFeature;
TLV_add(&ToSendTLV, GUI_INIT_TRYFEATURE, 1, (uint8_t*)&settings);
/*RpResistorValue*/
settings = DPM_USER_Settings[port].PWR_RpResistorValue;
TLV_add(&ToSendTLV, GUI_INIT_RPRESISTORVALUE, 1, (uint8_t*)&settings);
/*USBSupport*/
settings = DPM_USER_Settings[port].USB_Support;
TLV_add(&ToSendTLV, GUI_INIT_USBSUPPORT, 1, (uint8_t*)&settings);
/*USBDevice*/
settings = DPM_USER_Settings[port].USB_Device;
TLV_add(&ToSendTLV, GUI_INIT_USBDEVICE, 1, (uint8_t*)&settings);
/*USBHost*/
settings = DPM_USER_Settings[port].USB_Host;
TLV_add(&ToSendTLV, GUI_INIT_USBHOST, 1, (uint8_t*)&settings);
/*Externally_Powered*/
settings = DPM_USER_Settings[port].PWR_UnconstrainedPower;
TLV_add(&ToSendTLV, GUI_INIT_UNCONSTRAINED_POWERED, 1, (uint8_t*)&settings);
/*USBSuspendSupport*/
settings = DPM_USER_Settings[port].USB_SuspendSupport;
TLV_add(&ToSendTLV, GUI_INIT_USBSUSPENDSUPPORT, 1, (uint8_t*)&settings);
#if defined(MB1303)
/*VConnDischarge*/
TLV_add(&ToSendTLV, GUI_INIT_VCONNDISCHARGE, 2, (uint8_t*)&fake);
/*VConnLim*/
TLV_add(&ToSendTLV, GUI_INIT_VCONNILIM, 2, (uint8_t*)&fake);
/*VConnLimValue*/
TLV_add(&ToSendTLV, GUI_INIT_VCONNILIMVALUE, 2, (uint8_t*)&fake);
/*VConnMonitoring*/
TLV_add(&ToSendTLV, GUI_INIT_VCONNMONITORING, 2, (uint8_t*)&fake);
/*VConnThresholdUVLO*/
TLV_add(&ToSendTLV, GUI_INIT_VCONNTHRESHOLDUVLO, 2, (uint8_t*)&fake);
/*VConnSupply*/
TLV_add(&ToSendTLV, GUI_INIT_VCONNSUPPLY, 2, (uint8_t*)&fake);
#endif /*MB1303*/
TLV_deinit_encode(&ToSendTLV);
}
}
/**
* @brief Execution of the message received
* @note Generation of a TLV instruction to send in the context of DPM_MESSAGE
*/
static void Request_MessageReq(uint8_t PortNum, uint8_t* instruction, uint8_t *pEncodedMsg)
{
USBPD_StatusTypeDef status = USBPD_ERROR;
TLV_Received_Data process_tlv;
TLV_ToSend_Data send_tlv;
TLV_init_decode(&process_tlv, instruction);
TLV_init_encode(&send_tlv, __GUI_SET_TAG_ID((PortNum + 1), DPM_MESSAGE_CNF), TLV_SIZE_MAX, pEncodedMsg);
/*
In case there is an error, we use this variable to know when to send a DPM_MESSAGE_REJ
instead of a DPM_MESSAGE_CNF. This variable contains the cause if there is one.
*/
USBPD_GUI_Reject_Reason error = GUI_REJ_DPM_REJECT;
uint8_t tag;
uint16_t length;
uint8_t *value;
TLV_get(&process_tlv, &tag, &length, &value);
switch(tag)
/*
Each case should:
- Apply his specific request in the stack. If parameters are needed, they can be found in the value pointer
- If there is an error, set the error variable according to it (cf USBPD_GUI_Specification)
- Otherwise in case of success, do nothing else
*/
{
case GUI_MSG_GOTOMIN :
status = USBPD_DPM_RequestGotoMin(PortNum);
break;
case GUI_MSG_PING :
status = USBPD_DPM_RequestPing(PortNum);
break;
case GUI_MSG_GET_SRC_CAPA :
status = USBPD_DPM_RequestGetSourceCapability(PortNum);
break;
case GUI_MSG_GET_SNK_CAPA :
status = USBPD_DPM_RequestGetSinkCapability(PortNum);
break;
case GUI_MSG_DR_SWAP :
status = USBPD_DPM_RequestDataRoleSwap(PortNum);
break;
case GUI_MSG_PR_SWAP :
status = USBPD_DPM_RequestPowerRoleSwap(PortNum);
break;
case GUI_MSG_VCONN_SWAP :
status = USBPD_DPM_RequestVconnSwap(PortNum);
break;
case GUI_MSG_SOURCE_CAPA :
status = USBPD_DPM_RequestSourceCapability(PortNum);
break;
case GUI_MSG_REQUEST :
{
uint16_t voltage = 0;
uint8_t nb_expected_tag = 0;
uint8_t index_pdo = 0;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 2))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_RDOPOSITION == (USBPD_GUI_Tag_ParamMsg)tag)
{
index_pdo = value[0];
}
else if (GUI_PARAM_MSG_REQUESTEDVOLTAGE == (USBPD_GUI_Tag_ParamMsg)tag)
{
voltage = LE16(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (2 == nb_expected_tag)
{
status = USBPD_DPM_RequestMessageRequest(PortNum, index_pdo, voltage);
}
}
break;
case GUI_MSG_SOFT_RESET :
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
status = USBPD_DPM_RequestSoftReset(PortNum, (USBPD_SOPType_TypeDef)value[0]);
}
break;
case GUI_MSG_HARD_RESET :
status = USBPD_DPM_RequestHardReset(PortNum);
break;
case GUI_MSG_CABLE_RESET :
status = USBPD_DPM_RequestCableReset(PortNum);
break;
#if defined(_VDM) || defined(_VCONN_SUPPORT)
case GUI_MSG_VDM_DISCO_IDENT :
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
status = USBPD_DPM_RequestVDM_DiscoveryIdentify(PortNum, (USBPD_SOPType_TypeDef)value[0]);
}
break;
case GUI_MSG_VDM_DISCO_SVID :
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
status = USBPD_DPM_RequestVDM_DiscoverySVID(PortNum, (USBPD_SOPType_TypeDef)value[0]);
}
break;
case GUI_MSG_VDM_DISCO_MODE :
{
uint16_t svid = 0;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 2))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_SVDM_SVID == (USBPD_GUI_Tag_ParamMsg)tag)
{
svid = LE16(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (2 == nb_expected_tag)
{
status = USBPD_DPM_RequestVDM_DiscoveryMode(PortNum, (USBPD_SOPType_TypeDef)sop, svid);
}
}
break;
case GUI_MSG_VDM_ENTER_MODE :
{
uint16_t mode = 0, svid = 0;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 3))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_SVDM_SVID == (USBPD_GUI_Tag_ParamMsg)tag)
{
svid = LE16(&value[0]);
}
else if (GUI_PARAM_MSG_SVDM_MODEINDEX == (USBPD_GUI_Tag_ParamMsg)tag)
{
mode = LE16(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (3 == nb_expected_tag)
{
status = USBPD_DPM_RequestVDM_EnterMode(PortNum, (USBPD_SOPType_TypeDef)sop, svid, mode);
}
}
break;
case GUI_MSG_VDM_EXIT_MODE :
{
uint16_t svid = 0, mode = 0;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 3))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_SVDM_SVID == (USBPD_GUI_Tag_ParamMsg)tag)
{
svid = LE16(&value[0]);
}
else if (GUI_PARAM_MSG_SVDM_MODEINDEX == (USBPD_GUI_Tag_ParamMsg)tag)
{
mode = value[0];
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (3 == nb_expected_tag)
{
status = USBPD_DPM_RequestVDM_ExitMode(PortNum, (USBPD_SOPType_TypeDef)sop, svid, mode);
}
}
break;
case GUI_MSG_VDM_UNSTRUCTURED :
break;
#endif /* _VDM || _VCONN_SUPPORT */
#if defined(_VDM)
case GUI_MSG_DISPLAY_PORT_STATUS :
{
uint32_t dp_status;
uint16_t svid = 0;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 3))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_SVDM_SVID == (USBPD_GUI_Tag_ParamMsg)tag)
{
svid = LE16(&value[0]);
}
else if (GUI_PARAM_MSG_DP_STATUS == (USBPD_GUI_Tag_ParamMsg)tag)
{
dp_status = LE32(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (3 == nb_expected_tag)
{
status = USBPD_DPM_RequestDisplayPortStatus(PortNum, (USBPD_SOPType_TypeDef)sop, svid, &dp_status);
}
}
break;
case GUI_MSG_DISPLAY_PORT_CONFIG :
{
uint32_t dp_config;
uint16_t svid = 0;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 3))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_SVDM_SVID == (USBPD_GUI_Tag_ParamMsg)tag)
{
svid = LE16(&value[0]);
}
else if (GUI_PARAM_MSG_DP_CONFIGURE== (USBPD_GUI_Tag_ParamMsg)tag)
{
dp_config = LE32(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (3 == nb_expected_tag)
{
status = USBPD_DPM_RequestDisplayPortConfig(PortNum, (USBPD_SOPType_TypeDef)sop, svid, &dp_config);
}
}
break;
case GUI_MSG_DISPLAY_PORT_ATTENTION :
break;
case GUI_MSG_VDM_ATTENTION :
{
uint16_t svid = 0;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 2))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_SVDM_SVID == (USBPD_GUI_Tag_ParamMsg)tag)
{
svid = LE16(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (2 == nb_expected_tag)
{
status = USBPD_DPM_RequestAttention(PortNum, (USBPD_SOPType_TypeDef)sop, svid);
}
}
break;
#endif /* _VDM */
case GUI_MSG_FREE_TEXT :
{
uint8_t nb_expected_tag = 0;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 1))
{
nb_expected_tag++;
}
if (1 == nb_expected_tag)
{
status = Manage_FreeText(PortNum, value, length);
}
}
break;
#ifdef USBPD_REV30_SUPPORT
case GUI_MSG_FR_SWAP :
status = USBPD_DPM_RequestFastRoleSwap(PortNum);
break;
case GUI_MSG_GET_PPS_STATUS :
status = USBPD_DPM_RequestGetPPS_Status(PortNum);
break;
case GUI_MSG_GET_COUNTRY_CODES :
status = USBPD_DPM_RequestGetCountryCodes(PortNum);
break;
case GUI_MSG_GET_STATUS :
status = USBPD_DPM_RequestGetStatus(PortNum);
break;
case GUI_MSG_GET_SOURCE_CAPA_EXTENDED :
status = USBPD_DPM_RequestGetSourceCapabilityExt(PortNum);
break;
case GUI_MSG_GET_SINK_CAPA_EXTENDED :
status = USBPD_DPM_RequestGetSinkCapabilityExt(PortNum);
break;
case GUI_MSG_ALERT :
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_ALERTMSG == (USBPD_GUI_Tag_ParamMsg)tag)
{
USBPD_ADO_TypeDef alert;
alert.d32 = LE32(&value[0]);
status = USBPD_DPM_RequestAlert(PortNum, alert);
}
break;
case GUI_MSG_GET_COUNTRY_INFO :
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_COUNTRYCODE == (USBPD_GUI_Tag_ParamMsg)tag)
{
uint16_t country_code;
country_code = LE16(&value[0]);
status = USBPD_DPM_RequestGetCountryInfo(PortNum, country_code);
}
break;
case GUI_MSG_GET_BAT_CAPA :
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_BATTERYREF == (USBPD_GUI_Tag_ParamMsg)tag)
{
status = USBPD_DPM_RequestGetBatteryCapability(PortNum, (uint8_t*)&value[0]);
}
break;
case GUI_MSG_GET_BAT_STATUS :
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
if (GUI_PARAM_MSG_BATTERYREF == (USBPD_GUI_Tag_ParamMsg)tag)
{
status = USBPD_DPM_RequestGetBatteryStatus(PortNum, (uint8_t*)&value[0]);
}
break;
case GUI_MSG_GET_MANU_INFO :
{
uint16_t manu_info;
uint8_t nb_expected_tag = 0;
uint8_t sop = USBPD_SOPTYPE_SOP;
if (length > TLV_SIZE_MAX) break;
TLV_get(&process_tlv, &tag, &length, &value);
while((0 != length) && (TLV_SIZE_MAX > length) && (nb_expected_tag < 2))
{
nb_expected_tag++;
if (GUI_PARAM_MSG_SOPTYPE == (USBPD_GUI_Tag_ParamMsg)tag)
{
sop = value[0];
}
else if (GUI_PARAM_MSG_MANUINFODATA == (USBPD_GUI_Tag_ParamMsg)tag)
{
manu_info = LE16(&value[0]);
}
TLV_get(&process_tlv, &tag, &length, &value);
}
if (2 == nb_expected_tag)
{
status = USBPD_DPM_RequestGetManufacturerInfo(PortNum, (USBPD_SOPType_TypeDef)sop, (uint8_t*)&manu_info);
}
}
break;
case GUI_MSG_SECU_REQUEST :
status = USBPD_DPM_RequestSecurityRequest(PortNum);
break;
case GUI_MSG_FIRM_UPDATE_REQUEST :
break;
#endif /* USBPD_REV30_SUPPORT */
default :
break;
}
/* Only applies if an error was specified (= if the case couldn't success)*/
if (USBPD_OK != status)
{
switch (status)
{
case USBPD_BUSY:
error = GUI_REJ_DPM_NOT_READY;
break;
case USBPD_TIMEOUT:
error = GUI_REJ_DPM_TIMEOUT;
break;
default:
case USBPD_NOTSUPPORTED:
case USBPD_ERROR:
error = GUI_REJ_DPM_REJECT;
break;
}
TLV_deinit_encode(&send_tlv);
TLV_init_encode(&send_tlv, __GUI_SET_TAG_ID((PortNum + 1), DPM_MESSAGE_REJ), TLV_SIZE_MAX, pEncodedMsg); /* Turn the tag 0x0A into 0x0B to signal an error*/
TLV_addValue(&send_tlv, (uint8_t*)&error, 1);
}
TLV_deinit_encode(&send_tlv);
TLV_deinit_decode(&process_tlv);
}
/**
* @brief Application of the received configuration
* @note Generation of a TLV instruction to send in the context of DPM_CONFIG_SET
*/
static void Send_DpmConfigSetCnf(uint8_t PortNum, uint8_t* instruction, uint8_t *pEncodedMsg)
{
TLV_ToSend_Data send_tlv;
TLV_Received_Data process_tlv;
/*
In case there is an error, we use this variable to know when to send a DPM_CONFIG_SET instead
of a DPM_MESSAGE_CNF. This variable contains the cause if there is one.
*/
uint8_t *value;
uint16_t size;
uint16_t dcdrp = 0;
uint8_t error = 0xFF;
uint8_t param_not_applicated[GUI_PARAM_ALL]; /* List of parameters who could not be applied. */
uint8_t counter_param_not_applicated = 0; /* Counter of not applicated parameters */
uint8_t tag, flag_drp = 0, tdrp = 0;
TLV_init_decode(&process_tlv, instruction);
/* This is the pEncodedMsg can be sent as it is at this point, if there isn't any error during application of settings*/
TLV_init_encode(&send_tlv, __GUI_SET_TAG_ID((PortNum + 1), DPM_CONFIG_SET_CNF), TLV_SIZE_MAX, pEncodedMsg);
/* Do while loop, used to parse and apply each parameter */
while(0xFF != TLV_get(&process_tlv, &tag, &size, &value))
/*
As long as we haven't read all the parameters. If error is set, we continue to loop
to apply the other parameters if it's because of a DPM_REJECT
While loop, used to parse and apply each parameter
*/
{
switch((USBPD_GUI_Tag_Param)tag)
/*
Each case should:
- Apply his specific parameter. If data is needed, it can be found in the value pointer
- In case of success, do nothing else
- Otherwise if there is an error, set the error variable according to it (cf USBPD_GUI_Specification)
- If the error is DPM_REJECT (0x00), add the parameter tag to param_not_applicated, using the
counter counter_param_not_applicated. It allows to list the rejected parameters in the DPM_CONFIG_REJ
*/
{
case GUI_PARAM_SOP :
#if !defined(USBPDCORE_LIB_NO_PD)
/* SOP & SOP1 & SOP2 */
/* SOP1_Debug & SOP2_Debug not implemented */
DPM_Settings[PortNum].PE_SupportedSOP = value[0];
#endif /* !USBPDCORE_LIB_NO_PD */
break;
#if defined(USBPD_REV30_SUPPORT)
case GUI_PARAM_FASTROLESWAP :
/*FastRoleSwap*/
DPM_Settings[PortNum].PE_PD3_Support.d.PE_FastRoleSwapSupport = value[0];
break;
#endif /*USBPD_REV30_SUPPORT*/
case GUI_PARAM_DATAROLESWAP_TO_UFP :
/*DataRoleSwap to UFP */
DPM_USER_Settings[PortNum].PE_DR_Swap_To_UFP = value[0];
break;
case GUI_PARAM_DATAROLESWAP_TO_DFP :
/*DataRoleSwap to DFP */
DPM_USER_Settings[PortNum].PE_DR_Swap_To_DFP = value[0];
break;
case GUI_PARAM_DEFAULTPOWERROLE :
/*DefaultPowerRole*/
DPM_Settings[PortNum].PE_DefaultRole = (USBPD_PortPowerRole_TypeDef)value[0];
break;
#if !defined(USBPDCORE_LIB_NO_PD)
case GUI_PARAM_DRP_SUPPORT :
/*DRP_Support*/
DPM_Settings[PortNum].PE_RoleSwap = value[0];
break;
case GUI_PARAM_CADROLETOGGLE :
/*CADRoleToggle*/
DPM_Settings[PortNum].CAD_RoleToggle = value[0];
break;
case GUI_PARAM_PE_SCAP_HR :
/*PE_SCAP_HR*/
DPM_Settings[PortNum].PE_CapscounterSupport = value[0];
break;
case GUI_PARAM_VCONNSWAP :
/*VConnSwap*/
DPM_USER_Settings[PortNum].PE_VconnSwap = value[0];
break;
#if defined(_VDM)
case GUI_PARAM_VDM_SUPPORT :
/* DRP Support */
DPM_Settings[PortNum].PE_VDMSupport = value[0];
break;
#endif /*_VDM*/
case GUI_PARAM_PING_SUPPORT :
/* Ping Support */
DPM_Settings[PortNum].PE_PingSupport = value[0];
break;
#if defined(USBPD_REV30_SUPPORT)
case GUI_PARAM_PPS_SUPPORT :
DPM_Settings[PortNum].PE_PD3_Support.PD3_Support = LE16(&value[0]);
break;
#endif /*USBPD_REV30_SUPPORT*/
#endif /* !USBPDCORE_LIB_NO_PD */
#if defined(_SNK) || defined(_DRP)
case GUI_PARAM_SNK_PDO :
{
uint32_t index_pdo, index_gui;
uint32_t pdo;
#if USBPD_PORT_COUNT==2
if (USBPD_PORT_0 == PortNum)
#endif /* USBPD_PORT_COUNT==2 */
{
memset(PORT0_PDO_ListSNK, 0, sizeof(PORT0_PDO_ListSNK));
for (index_pdo = 0, index_gui = 0; index_gui < size; index_pdo++)
{
pdo = LE32(&value[index_gui]);
PORT0_PDO_ListSNK[index_pdo] = pdo;
index_gui = index_gui + 4;
}
USBPD_NbPDO[0] = (size / 4);
UpdateSNKPowerPort0();
}
#if USBPD_PORT_COUNT==2
else
{
memset(PORT1_PDO_ListSNK, 0, sizeof(PORT1_PDO_ListSNK));
for (index_pdo = 0, index_gui = 0; index_gui < size; index_pdo++)
{
pdo = LE32(&value[index_gui]);
PORT1_PDO_ListSNK[index_pdo] = pdo;
index_gui = index_gui + 4;
}
USBPD_NbPDO[2] = (size / 4);
UpdateSNKPowerPort1();
}
#endif /* USBPD_PORT_COUNT==2 */
}
break;
#endif /* (_SNK) || (_DRP) */
#if defined(_SRC) || defined(_DRP)
case GUI_PARAM_SRC_PDO :
{
uint32_t index_pdo, index_gui;
uint32_t pdo;
#if USBPD_PORT_COUNT==2
if (USBPD_PORT_0 == PortNum)
#endif /* USBPD_PORT_COUNT==2 */
{
memset(PORT0_PDO_ListSRC, 0, sizeof(PORT0_PDO_ListSRC));
for (index_pdo = 0, index_gui = 0; index_gui < size; index_pdo++)
{
pdo = LE32(&value[index_gui]);
PORT0_PDO_ListSRC[index_pdo] = pdo;
index_gui = index_gui + 4;
}
USBPD_NbPDO[1] = (size / 4);
}
#if USBPD_PORT_COUNT==2
else
{
memset(PORT1_PDO_ListSRC, 0, sizeof(PORT1_PDO_ListSRC));
for (index_pdo = 0, index_gui = 0; index_gui < size; index_pdo++)
{
pdo = LE32(&value[index_gui]);
PORT1_PDO_ListSRC[index_pdo] = pdo;
index_gui = index_gui + 4;
}
USBPD_NbPDO[3] = (size / 4);
}
#endif /* USBPD_PORT_COUNT==2 */
}
break;
#endif /* (_SRC) || (_DRP) */
case GUI_PARAM_TDRP :
tdrp = value[0];
DPM_USER_Settings[PortNum].CAD_tDRP = tdrp;
flag_drp = 1;
break;
case GUI_PARAM_DCSRC_DRP :
dcdrp = value[0];
DPM_USER_Settings[PortNum].CAD_dcSRC_DRP = dcdrp;
flag_drp = 1;
break;
case GUI_PARAM_RESPONDS_TO_DISCOV_SOP :
DPM_Settings[PortNum].PE_RespondsToDiscovSOP = value[0];
break;
case GUI_PARAM_ATTEMPTS_DISCOV_SOP :
DPM_Settings[PortNum].PE_AttemptsDiscovSOP = value[0];
break;
case GUI_PARAM_XID_SOP :
DPM_ID_Settings[PortNum].XID = LE32(&value[0]);
break;
case GUI_PARAM_USB_VID_SOP :
DPM_ID_Settings[PortNum].VID = LE16(&value[0]);
break;
case GUI_PARAM_PID_SOP :
DPM_ID_Settings[PortNum].PID = LE16(&value[0]);
break;
#if defined(_VDM)
case GUI_PARAM_DATA_CAPABLE_AS_USB_HOST_SOP :
DPM_VDM_Settings[PortNum].VDM_USBHostSupport = (USBPD_USBCapa_TypeDef)value[0];
break;
case GUI_PARAM_DATA_CAPABLE_AS_USB_DEVICE_SOP :
DPM_VDM_Settings[PortNum].VDM_USBDeviceSupport = (USBPD_USBCapa_TypeDef)value[0];
break;
case GUI_PARAM_PRODUCT_TYPE_SOP :
DPM_VDM_Settings[PortNum].VDM_ProductTypeUFPorCP= (USBPD_ProductType_TypeDef)value[0];
break;
case GUI_PARAM_MODAL_OPERATION_SUPPORTED_SOP :
DPM_VDM_Settings[PortNum].VDM_ModalOperation = (USBPD_ModalOp_TypeDef)value[0];
break;
case GUI_PARAM_BCDDEVICE_SOP :
DPM_VDM_Settings[PortNum].VDM_bcdDevice_SOP = LE16(&value[0]);
break;
#endif /* _VDM */
case GUI_PARAM_MEASUREREPORTING :
/* MeasurementReporting */
GUI_USER_Params[PortNum].u.MeasurementReporting = value[0];
break;
#if defined(USBPD_REV30_SUPPORT)
#if _MANU_INFO
case GUI_PARAM_MANUINFOPORT_VID :
DPM_USER_Settings[PortNum].DPM_ManuInfoPort.VID = LE16(&value[0]);
DPM_USER_Settings[PortNum].DPM_ManuInfoPort.PID = LE16(&value[2]);
size -= 4;
memcpy(DPM_USER_Settings[PortNum].DPM_ManuInfoPort.ManuString, &value[4], size);
break;
#endif /* _MANU_INFO */
#endif /*USBPD_REV30_SUPPORT*/
default :
error = GUI_REJ_DPM_REJECT;
param_not_applicated[counter_param_not_applicated] = tag;
counter_param_not_applicated++;
break;
}
}
#if !defined(USBPDCORE_LIB_NO_PD)
/* Updtate CAD_SNKToggleTime & CAD_SRCToggleTime only if TDRP and/or DC_SRC_DRP have been received */
if (1 == flag_drp)
{
uint16_t calcul;
if (0 == tdrp)
{
tdrp = DPM_Settings[PortNum].CAD_SNKToggleTime + DPM_Settings[PortNum].CAD_SRCToggleTime;
}
if (0 == dcdrp)
{
dcdrp = (DPM_Settings[PortNum].CAD_SRCToggleTime * 100) / (DPM_Settings[PortNum].CAD_SNKToggleTime + DPM_Settings[PortNum].CAD_SRCToggleTime);
}
calcul = (tdrp * dcdrp) / 100;
DPM_Settings[PortNum].CAD_SRCToggleTime = (uint8_t)calcul;
calcul = tdrp * (100 - dcdrp) / 100;
DPM_Settings[PortNum].CAD_SNKToggleTime = (uint8_t)calcul;
}
#endif /* !USBPDCORE_LIB_NO_PD */
/* Only applies if an error was specified. Will send a DPM_CONFIG_REJ instead of DPM_CONFIG_SET_CNF*/
if(error != 0xFF)
{
TLV_deinit_encode(&send_tlv);
TLV_init_encode(&send_tlv, __GUI_SET_TAG_ID((PortNum + 1), DPM_CONFIG_REJ), TLV_SIZE_MAX, pEncodedMsg);
TLV_addValue(&send_tlv, &error, 1);
/* If the cause of error is DPM_REJECT, we have to list the tag of parameters which didn't pass */
if(!error)
{
uint32_t index;
for(index = 0; index < counter_param_not_applicated; index++)
{
TLV_addValue(&send_tlv, &param_not_applicated[index], 1);
}
}
TLV_deinit_encode(&send_tlv);
}
}
static void Send_DpmConfigGetCnf(uint8_t PortNum, uint8_t* instruction, uint8_t *pEncodedMsg)
{
TLV_ToSend_Data send_tlv;
TLV_init_encode(&send_tlv, __GUI_SET_TAG_ID((PortNum + 1), DPM_CONFIG_GET_CNF), TLV_SIZE_MAX, pEncodedMsg);
uint16_t length = TLV_get_string_length(instruction) - TLV_HEADER_SIZE;
uint8_t index = 0;
uint8_t param;
/* This is a state machine. */
do
{
/* If there is no parameters, we go through each case of the state machine in one pass. (conditionnal breaks) */
if(0 == length)
{
param = GUI_PARAM_ALL;
}
else
{
/* If there are, we loop the state machine and go through one case each time. */
param = instruction[TLV_VALUE_POSITION + index];
}
/*
Each case should simply use the TLV_add function to insert his corresponding data,
as suggested in comment. Manual cast to (uint8_t *) may be required.
*/
switch((USBPD_GUI_Tag_Param)param)
{
case GUI_PARAM_ALL :
#if !defined(USBPDCORE_LIB_NO_PD)
case GUI_PARAM_SOP :
{
/* SOP & SOP1 & SOP2 */
/* SOP1_Debug & SOP2_Debug not implemented */
uint8_t settings = DPM_Settings[PortNum].PE_SupportedSOP;
TLV_add(&send_tlv, GUI_PARAM_SOP, 1, &settings);
if(0 != length)
{
break;
}
}
#if defined(USBPD_REV30_SUPPORT)
case GUI_PARAM_FASTROLESWAP :
{
/*FastRoleSwap*/
uint8_t settings = DPM_Settings[PortNum].PE_PD3_Support.d.PE_FastRoleSwapSupport;
TLV_add(&send_tlv, GUI_PARAM_FASTROLESWAP, 1, &settings);
if(0 != length)
{
break;
}
}
#endif /*USBPD_REV30_SUPPORT*/
#endif /* !USBPDCORE_LIB_NO_PD */
case GUI_PARAM_DATAROLESWAP_TO_UFP :
{
/* DataRoleSwap to UFP */
uint8_t settings = DPM_USER_Settings[PortNum].PE_DR_Swap_To_UFP;
TLV_add(&send_tlv, GUI_PARAM_DATAROLESWAP_TO_UFP, 1, &settings);
if(0 != length)
{
break;
}
}
case GUI_PARAM_DATAROLESWAP_TO_DFP :
{
/* DataRoleSwap to DFP */
uint8_t settings = DPM_USER_Settings[PortNum].PE_DR_Swap_To_DFP;
TLV_add(&send_tlv, GUI_PARAM_DATAROLESWAP_TO_DFP, 1, &settings);
if(0 != length)
{
break;
}
}
case GUI_PARAM_DEFAULTPOWERROLE :
{
/*DefaultPowerRole*/
uint8_t settings = DPM_Settings[PortNum].PE_DefaultRole;
TLV_add(&send_tlv, GUI_PARAM_DEFAULTPOWERROLE, 1, &settings);
if(0 != length)
{
break;
}
}
#if !defined(USBPDCORE_LIB_NO_PD)
case GUI_PARAM_DRP_SUPPORT :
{
/*DRP_Support*/
uint8_t settings = DPM_Settings[PortNum].PE_RoleSwap;
TLV_add(&send_tlv, GUI_PARAM_DRP_SUPPORT, 1, &settings);
if(0 != length)
{
break;
}
}
case GUI_PARAM_CADROLETOGGLE :
{
/*CADRoleToggle*/
uint8_t settings = DPM_Settings[PortNum].CAD_RoleToggle;
TLV_add(&send_tlv, GUI_PARAM_CADROLETOGGLE, 1, &settings);
if(0 != length)
{
break;
}
}
case GUI_PARAM_PE_SCAP_HR :
{
/*PE_SCAP_HR*/
uint8_t settings = DPM_Settings[PortNum].PE_CapscounterSupport;
TLV_add(&send_tlv, GUI_PARAM_PE_SCAP_HR, 1, &settings);
if(0 != length)
{
break;
}
}
#if defined(_VDM)
case GUI_PARAM_VDM_SUPPORT :
{
/* DRP Support */
uint8_t settings = DPM_Settings[PortNum].PE_VDMSupport;
TLV_add(&send_tlv, GUI_PARAM_VDM_SUPPORT, 1, &settings);
if(0 != length)
{
break;
}
}
#endif /*_VDM*/
case GUI_PARAM_PING_SUPPORT :
{
/* Ping Support */
uint8_t settings = DPM_Settings[PortNum].PE_PingSupport;
TLV_add(&send_tlv, GUI_PARAM_PING_SUPPORT, 1, &settings);
if(0 != length)
{
break;
}
}
#if defined(USBPD_REV30_SUPPORT)
case GUI_PARAM_PPS_SUPPORT :
{
/* PD3 Support */
uint16_t settings = DPM_Settings[PortNum].PE_PD3_Support.PD3_Support;
TLV_add(&send_tlv, GUI_PARAM_PPS_SUPPORT, 2, (uint8_t*)&settings);
if(0 != length)
{
break;
}
}
#endif /*USBPD_REV30_SUPPORT*/
#endif /* !USBPDCORE_LIB_NO_PD */
case GUI_PARAM_VCONNSWAP :
{
/*VConnSwap*/
uint8_t settings = DPM_USER_Settings[PortNum].PE_VconnSwap;
TLV_add(&send_tlv, GUI_PARAM_VCONNSWAP, 1, &settings);
if(0 != length)
{
break;
}
}
#if defined(_SNK) || defined(_DRP)
case GUI_PARAM_SNK_PDO :
{
uint8_t* list_pdo;
uint8_t nb_pdo;
#if USBPD_PORT_COUNT==2
if (USBPD_PORT_0 == PortNum)
#endif /* USBPD_PORT_COUNT==2 */
{
nb_pdo = USBPD_NbPDO[0];
list_pdo = (uint8_t*)PORT0_PDO_ListSNK;
}
#if USBPD_PORT_COUNT==2
else
{
nb_pdo = USBPD_NbPDO[2];
list_pdo = (uint8_t*)PORT1_PDO_ListSNK;
}
#endif /* USBPD_PORT_COUNT==2 */
TLV_add(&send_tlv, GUI_PARAM_SNK_PDO, nb_pdo * 4, list_pdo);
}
if(0 != length)
{
break;
}
#endif /* _SNK || _DRP */
#if defined(_SRC) || defined(_DRP)
case GUI_PARAM_SRC_PDO :
{
uint8_t* list_pdo;
uint8_t nb_pdo;
#if USBPD_PORT_COUNT==2
if (USBPD_PORT_0 == PortNum)
#endif /* USBPD_PORT_COUNT==2 */
{
nb_pdo = USBPD_NbPDO[1];
list_pdo = (uint8_t*)PORT0_PDO_ListSRC;
}
#if USBPD_PORT_COUNT==2
else
{
nb_pdo = USBPD_NbPDO[3];
list_pdo = (uint8_t*)PORT1_PDO_ListSRC;
}
#endif /* USBPD_PORT_COUNT==2 */
TLV_add(&send_tlv, GUI_PARAM_SRC_PDO, nb_pdo * 4, list_pdo);
}
if(0 != length)
{
break;
}
#endif /* _SRC || _DRP */
case GUI_PARAM_TDRP :
{
/* Calculate the current value of tDRP (value between 50ms and 100ms) */
uint8_t value = DPM_USER_Settings[PortNum].CAD_tDRP;
TLV_add(&send_tlv, GUI_PARAM_TDRP, 1, &value);
}
if(0 != length)
{
break;
}
case GUI_PARAM_DCSRC_DRP :
{
/* Calculate the current value of tDRP (value between 50ms and 100ms) */
uint8_t value = DPM_USER_Settings[PortNum].CAD_dcSRC_DRP;
TLV_add(&send_tlv, GUI_PARAM_DCSRC_DRP, 1, &value);
}
if(0 != length)
{
break;
}
#if !defined(USBPDCORE_LIB_NO_PD)
case GUI_PARAM_RESPONDS_TO_DISCOV_SOP :
{
uint8_t settings = DPM_Settings[PortNum].PE_RespondsToDiscovSOP;
TLV_add(&send_tlv, GUI_PARAM_RESPONDS_TO_DISCOV_SOP, 1, &settings);
}
if(0 != length)
{
break;
}
case GUI_PARAM_ATTEMPTS_DISCOV_SOP :
{
uint8_t settings = DPM_Settings[PortNum].PE_AttemptsDiscovSOP;
TLV_add(&send_tlv, GUI_PARAM_ATTEMPTS_DISCOV_SOP, 1, &settings);
}
if(0 != length)
{
break;
}
#endif /* !USBPDCORE_LIB_NO_PD */
case GUI_PARAM_XID_SOP :
{
uint32_t value = DPM_ID_Settings[PortNum].XID;
TLV_add(&send_tlv, GUI_PARAM_XID_SOP, 4, (uint8_t*)&value);
}
if(0 != length)
{
break;
}
case GUI_PARAM_USB_VID_SOP :
{
uint16_t value = DPM_ID_Settings[PortNum].VID;
TLV_add(&send_tlv, GUI_PARAM_USB_VID_SOP, 2, (uint8_t*)&value);
}
if(0 != length)
{
break;
}
case GUI_PARAM_PID_SOP :
{
uint16_t value = DPM_ID_Settings[PortNum].PID;
TLV_add(&send_tlv, GUI_PARAM_PID_SOP, 2, (uint8_t*)&value);
}
if(0 != length)
{
break;
}
#if defined(_VDM)
case GUI_PARAM_DATA_CAPABLE_AS_USB_HOST_SOP :
{
uint8_t settings = DPM_VDM_Settings[PortNum].VDM_USBHostSupport;
TLV_add(&send_tlv, GUI_PARAM_DATA_CAPABLE_AS_USB_HOST_SOP, 1, &settings);
}
if(0 != length)
{
break;
}
case GUI_PARAM_DATA_CAPABLE_AS_USB_DEVICE_SOP :
{
uint8_t settings = DPM_VDM_Settings[PortNum].VDM_USBDeviceSupport;
TLV_add(&send_tlv, GUI_PARAM_DATA_CAPABLE_AS_USB_DEVICE_SOP, 1, &settings);
}
if(0 != length)
{
break;
}
case GUI_PARAM_PRODUCT_TYPE_SOP :
{
uint8_t settings = DPM_VDM_Settings[PortNum].VDM_ProductTypeUFPorCP;
TLV_add(&send_tlv, GUI_PARAM_PRODUCT_TYPE_SOP, 1, &settings);
}
if(0 != length)
{
break;
}
case GUI_PARAM_MODAL_OPERATION_SUPPORTED_SOP :
{
uint8_t settings = DPM_VDM_Settings[PortNum].VDM_ModalOperation;
TLV_add(&send_tlv, GUI_PARAM_MODAL_OPERATION_SUPPORTED_SOP, 1, &settings);
}
if(0 != length)
{
break;
}
case GUI_PARAM_BCDDEVICE_SOP :
{
uint16_t value = DPM_VDM_Settings[PortNum].VDM_bcdDevice_SOP;
TLV_add(&send_tlv, GUI_PARAM_BCDDEVICE_SOP, 2, (uint8_t*)&value);
}
if(0 != length)
{
break;
}
#endif /* _VDM */
case GUI_PARAM_MEASUREREPORTING :
{
uint8_t settings = GUI_USER_Params[PortNum].u.MeasurementReporting;
TLV_add(&send_tlv, GUI_PARAM_MEASUREREPORTING, 1, &settings);
}
if(0 != length)
{
break;
}
#if defined(USBPD_REV30_SUPPORT)
#if _MANU_INFO
case GUI_PARAM_MANUINFOPORT_VID :
{
uint8_t size = sizeof(DPM_USER_Settings[PortNum].DPM_ManuInfoPort.ManuString) + 4;
TLV_add(&send_tlv, GUI_PARAM_MANUINFOPORT_VID, size, (uint8_t*)&DPM_USER_Settings[PortNum].DPM_ManuInfoPort);
}
if(0 != length)
{
break;
}
#endif /* _MANU_INFO */
#endif /*USBPD_REV30_SUPPORT*/
default:
if(0 != length)
{
/* At least 1 parameter does not exist */
TLV_deinit_encode(&send_tlv);
Send_DpmConfigGetRej(PortNum, pEncodedMsg, GUI_REJ_DPM_INVALID_MESSAGE);
goto __end;
}
break;
}
index++;
/*
Loop until we haven't processed each specified parameter.
If there weren't any (length = 0), we exit the loop after one execution.
*/
} while(index < length);
__end:
TLV_deinit_encode(&send_tlv);
}
static void Send_DpmConfigGetRej(uint8_t PortNum, uint8_t *pEncodedMsg, USBPD_GUI_Reject_Reason RejectReason)
{
TLV_ToSend_Data send_tlv;
TLV_init_encode(&send_tlv, DPM_CONFIG_REJ, TLV_SIZE_MAX, pEncodedMsg);
TLV_add(&send_tlv, RejectReason, 0, NULL);
TLV_deinit_encode(&send_tlv);
}
static void Send_DpmMessageRej(uint8_t PortNum, uint8_t *pEncodedMsg, USBPD_GUI_Reject_Reason RejectReason)
{
TLV_ToSend_Data send_tlv;
TLV_init_encode(&send_tlv, DPM_MESSAGE_REJ, TLV_SIZE_MAX, pEncodedMsg);
TLV_add(&send_tlv, RejectReason, 0, NULL);
TLV_deinit_encode(&send_tlv);
}
static void Send_DpmRegisterReadCnf(uint8_t PortNum, uint8_t *pEncodedMsg, uint8_t param)
{
TLV_ToSend_Data ToSendTLV;
TLV_init_encode(&ToSendTLV, __GUI_SET_TAG_ID((PortNum +1), DPM_REGISTER_READ_CNF), TLV_SIZE_MAX, pEncodedMsg);
uint8_t stateMachineArray[GUI_REG_NUMBER_OF_REGISTERS] = {
GUI_REG_VENDOR_ID, GUI_REG_PRODUCT_ID, GUI_REG_DEVICE_ID, GUI_REG_USBTYPEC_REV,
GUI_REG_USBPD_REV_VER, GUI_REG_USBPD_INTERFACE_REV, GUI_REG_ALERT, GUI_REG_ALERT_MASK,
GUI_REG_POWER_STATUS_MASK, GUI_REG_FAULT_STATUS_MASK, GUI_REG_CONFIG_STANDARD_OUTPUT,
GUI_REG_TCPC_CONTROL, GUI_REG_ROLE_CONTROL, GUI_REG_FAULT_CONTROL, GUI_REG_POWER_CONTROL,
GUI_REG_CC_STATUS, GUI_REG_POWER_STATUS, GUI_REG_FAULT_STATUS, GUI_REG_COMMAND, GUI_REG_DECIVE_CAP1,
GUI_REG_DECIVE_CAP2, GUI_REG_STD_INPUT_CAP, GUI_REG_STD_OUTPUT_CAP, GUI_REG_MSG_HEADER_INFO,
GUI_REG_RX_DETECT, GUI_REG_RX_BYTE_COUNT, GUI_REG_RX_BUFFER_FRAME_TYPE, GUI_REG_RX_HEADER,
GUI_REG_RX_DATA, GUI_REG_TRANSMIT, GUI_REG_TX_BYTE_COUNT, GUI_REG_TX_HEADER, GUI_REG_TX_DATA,
GUI_REG_VBUS_VOLTAGE, GUI_REG_VBUS_SINK_DISCONNECT_THRESHOLD, GUI_REG_VBUS_STOP_DISCHARGE_THRESHOLD,
GUI_REG_VBUS_VOLTAGE_ALARM_HI_CFG, GUI_REG_VBUS_VOLTAGE_ALARM_LO_CFG, GUI_REG_VENDOR_DATA
};
uint8_t counter = 0;
/* If param is not at 0xFF, then it means we only want one parameter.
We then have to get out of the state machine after the first state */
if(param != 0xFF)
{
*stateMachineArray = param;
}
do
{
switch(stateMachineArray[counter])
/*
In each case, the register needs to be read. Inclusion in the TLV which
is going to be sent has to be done with TLV_add().
*/
{
case GUI_REG_VENDOR_ID :
break;
case GUI_REG_PRODUCT_ID :
break;
case GUI_REG_DEVICE_ID :
break;
case GUI_REG_USBTYPEC_REV :
break;
case GUI_REG_USBPD_REV_VER :
break;
case GUI_REG_USBPD_INTERFACE_REV :
break;
case GUI_REG_ALERT :
break;
case GUI_REG_ALERT_MASK :
break;
case GUI_REG_POWER_STATUS_MASK :
break;
case GUI_REG_FAULT_STATUS_MASK :
break;
case GUI_REG_CONFIG_STANDARD_OUTPUT :
break;
case GUI_REG_TCPC_CONTROL :
break;
case GUI_REG_ROLE_CONTROL :
break;
case GUI_REG_FAULT_CONTROL :
break;
case GUI_REG_POWER_CONTROL :
break;
case GUI_REG_CC_STATUS :
break;
case GUI_REG_POWER_STATUS :
break;
case GUI_REG_FAULT_STATUS :
break;
case GUI_REG_COMMAND :
break;
case GUI_REG_DECIVE_CAP1 :
break;
case GUI_REG_DECIVE_CAP2 :
break;
case GUI_REG_STD_INPUT_CAP :
break;
case GUI_REG_STD_OUTPUT_CAP :
break;
case GUI_REG_MSG_HEADER_INFO :
break;
case GUI_REG_RX_DETECT :
break;
case GUI_REG_RX_BYTE_COUNT :
break;
case GUI_REG_RX_BUFFER_FRAME_TYPE :
break;
case GUI_REG_RX_HEADER :
break;
case GUI_REG_RX_DATA :
break;
case GUI_REG_TRANSMIT :
break;
case GUI_REG_TX_BYTE_COUNT :
break;
case GUI_REG_TX_HEADER :
break;
case GUI_REG_TX_DATA :
break;
case GUI_REG_VBUS_VOLTAGE :
break;
case GUI_REG_VBUS_SINK_DISCONNECT_THRESHOLD :
break;
case GUI_REG_VBUS_STOP_DISCHARGE_THRESHOLD :
break;
case GUI_REG_VBUS_VOLTAGE_ALARM_HI_CFG :
break;
case GUI_REG_VBUS_VOLTAGE_ALARM_LO_CFG :
break;
case GUI_REG_VENDOR_DATA :
break;
default :
break;
}
counter++;
} while(counter < GUI_REG_NUMBER_OF_REGISTERS && param != 0xFF);
TLV_deinit_encode(&ToSendTLV);
}
static void Send_DpmRegisterWriteCnf(uint8_t PortNum, uint8_t *pEncodedMsg, uint8_t *toProcess)
{
TLV_Received_Data ToProcessTLV;
TLV_init_decode(&ToProcessTLV, toProcess);
uint8_t registerName;
uint16_t registerSize;
uint8_t *registerValue;
TLV_get(&ToProcessTLV, &registerName, &registerSize, &registerValue);
switch(registerName)
/*
Each case should write the data pointed by registerValue in the appropriate register,
while taking into account the size of the data with registerSize.
*/
{
case GUI_REG_VENDOR_ID :
break;
case GUI_REG_PRODUCT_ID :
break;
case GUI_REG_DEVICE_ID :
break;
case GUI_REG_USBTYPEC_REV :
break;
case GUI_REG_USBPD_REV_VER :
break;
case GUI_REG_USBPD_INTERFACE_REV :
break;
case GUI_REG_ALERT :
break;
case GUI_REG_ALERT_MASK :
break;
case GUI_REG_POWER_STATUS_MASK :
break;
case GUI_REG_FAULT_STATUS_MASK :
break;
case GUI_REG_CONFIG_STANDARD_OUTPUT :
break;
case GUI_REG_TCPC_CONTROL :
break;
case GUI_REG_ROLE_CONTROL :
break;
case GUI_REG_FAULT_CONTROL :
break;
case GUI_REG_POWER_CONTROL :
break;
case GUI_REG_CC_STATUS :
break;
case GUI_REG_POWER_STATUS :
break;
case GUI_REG_FAULT_STATUS :
break;
case GUI_REG_COMMAND :
break;
case GUI_REG_DECIVE_CAP1 :
break;
case GUI_REG_DECIVE_CAP2 :
break;
case GUI_REG_STD_INPUT_CAP :
break;
case GUI_REG_STD_OUTPUT_CAP :
break;
case GUI_REG_MSG_HEADER_INFO :
break;
case GUI_REG_RX_DETECT :
break;
case GUI_REG_RX_BYTE_COUNT :
break;
case GUI_REG_RX_BUFFER_FRAME_TYPE :
break;
case GUI_REG_RX_HEADER :
break;
case GUI_REG_RX_DATA :
break;
case GUI_REG_TRANSMIT :
break;
case GUI_REG_TX_BYTE_COUNT :
break;
case GUI_REG_TX_HEADER :
break;
case GUI_REG_TX_DATA :
break;
case GUI_REG_VBUS_VOLTAGE :
break;
case GUI_REG_VBUS_SINK_DISCONNECT_THRESHOLD :
break;
case GUI_REG_VBUS_STOP_DISCHARGE_THRESHOLD :
break;
case GUI_REG_VBUS_VOLTAGE_ALARM_HI_CFG :
break;
case GUI_REG_VBUS_VOLTAGE_ALARM_LO_CFG :
break;
case GUI_REG_VENDOR_DATA :
break;
default :
break;
}
TLV_deinit_decode(&ToProcessTLV);
TLV_ToSend_Data ToSendTLV;
/* Generation of the empty response, as it should be done*/
TLV_init_encode(&ToSendTLV, __GUI_SET_TAG_ID((PortNum + 1), DPM_REGISTER_WRITE_CNF), 12, pEncodedMsg);
TLV_deinit_encode(&ToSendTLV);
}
/**
* @brief Manage Free text sent by the GUI
* @param PortNum The current port number
* @param pPayload Pointer of the text to manage
* @param Size Size of the text
* @retval USBPD Status
*/
static USBPD_StatusTypeDef Manage_FreeText(uint8_t PortNum, uint8_t *pPayload, uint16_t Size)
{
USBPD_StatusTypeDef _status = USBPD_FAIL;
if (NULL != pCB_FreeText)
{
pCB_FreeText(PortNum, pPayload, Size);
_status = USBPD_OK;
}
return _status;
}
#if defined(_SNK) || defined(_DRP)
/**
* @brief Function to update SNK PDO and power user settings on Port0
* @retval None
*/
static void UpdateSNKPowerPort0(void)
{
USBPD_PDO_TypeDef pdo;
uint32_t _max_power = 0;
uint16_t _voltage = 0, _current = 0, _power = 0;
uint16_t _min_voltage = 0xFFFF, _max_voltage = 0, _max_current = 0;
for (uint32_t _index = 0; _index < USBPD_NbPDO[0]; _index++)
{
pdo.d32 = PORT0_PDO_ListSNK[_index];
switch (pdo.GenericPDO.PowerObject)
{
case USBPD_CORE_PDO_TYPE_FIXED: /*!< Fixed Supply PDO */
_voltage = GUI_DECODE_50MV(pdo.SNKFixedPDO.VoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_current = GUI_DECODE_10MA(pdo.SNKFixedPDO.OperationalCurrentIn10mAunits);
GUI_UPDATE_CURRENT_MAX(_current, _max_current);
break;
case USBPD_CORE_PDO_TYPE_BATTERY: /*!< Battery Supply PDO */
_voltage = GUI_DECODE_50MV(pdo.SNKBatteryPDO.MinVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
_voltage = GUI_DECODE_50MV(pdo.SNKBatteryPDO.MaxVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_power = GUI_DECODE_MW(pdo.SNKBatteryPDO.OperationalPowerIn250mWunits);
GUI_UPDATE_POWER_MAX(_power, _max_power);
break;
case USBPD_CORE_PDO_TYPE_VARIABLE: /*!< Variable Supply (non-battery) PDO */
_voltage = GUI_DECODE_50MV(pdo.SNKVariablePDO.MinVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
_voltage = GUI_DECODE_50MV(pdo.SNKVariablePDO.MaxVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_current = GUI_DECODE_10MA(pdo.SNKVariablePDO.OperationalCurrentIn10mAunits);
GUI_UPDATE_CURRENT_MAX(_current, _max_current);
break;
#if _PPS
case USBPD_CORE_PDO_TYPE_APDO: /*!< Augmented Power Data Object (APDO) */
_voltage = GUI_DECODE_100MV(pdo.SRCSNKAPDO.MinVoltageIn100mV);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
_voltage = GUI_DECODE_100MV(pdo.SRCSNKAPDO.MaxVoltageIn100mV);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_current = GUI_DECODE_50MA(pdo.SRCSNKAPDO.MaxCurrentIn50mAunits);
GUI_UPDATE_CURRENT_MAX(_current, _max_current);
break;
#endif /*_USBPD_REV30_SUPPORT && PPS*/
default:
break;
}
}
GUI_CHECK_VOLTAGE_MIN(_min_voltage, DPM_USER_Settings[USBPD_PORT_0].DPM_SNKRequestedPower.MinOperatingVoltageInmVunits);
GUI_CHECK_VOLTAGE_MAX(_max_voltage, DPM_USER_Settings[USBPD_PORT_0].DPM_SNKRequestedPower.MaxOperatingVoltageInmVunits);
GUI_CHECK_CURRENT_MAX(_max_current, DPM_USER_Settings[USBPD_PORT_0].DPM_SNKRequestedPower.MaxOperatingCurrentInmAunits);
_max_power = (_max_voltage * _max_current) / 1000;
GUI_CHECK_POWER_MAX(_max_power, DPM_USER_Settings[USBPD_PORT_0].DPM_SNKRequestedPower.MaxOperatingPowerInmWunits);
}
#if USBPD_PORT_COUNT==2
/**
* @brief Function to update SNK PDO and power user settings on Port1
* @retval None
*/
static void UpdateSNKPowerPort1(void)
{
USBPD_PDO_TypeDef pdo;
uint32_t _max_power = 0;
uint16_t _voltage = 0, _current = 0, _power = 0;
uint16_t _min_voltage = 0xFFFF, _max_voltage = 0, _max_current = 0;
for (uint32_t _index = 0; _index < USBPD_NbPDO[2]; _index++)
{
pdo.d32 = PORT1_PDO_ListSNK[_index];
switch (pdo.GenericPDO.PowerObject)
{
case USBPD_CORE_PDO_TYPE_FIXED: /*!< Fixed Supply PDO */
_voltage = GUI_DECODE_50MV(pdo.SNKFixedPDO.VoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_current = GUI_DECODE_10MA(pdo.SNKFixedPDO.OperationalCurrentIn10mAunits);
GUI_UPDATE_CURRENT_MAX(_current, _max_current);
break;
case USBPD_CORE_PDO_TYPE_BATTERY: /*!< Battery Supply PDO */
_voltage = GUI_DECODE_50MV(pdo.SNKBatteryPDO.MinVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
_voltage = GUI_DECODE_50MV(pdo.SNKBatteryPDO.MaxVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_power = GUI_DECODE_MW(pdo.SNKBatteryPDO.OperationalPowerIn250mWunits);
GUI_UPDATE_POWER_MAX(_power, _max_power);
break;
case USBPD_CORE_PDO_TYPE_VARIABLE: /*!< Variable Supply (non-battery) PDO */
_voltage = GUI_DECODE_50MV(pdo.SNKVariablePDO.MinVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
_voltage = GUI_DECODE_50MV(pdo.SNKVariablePDO.MaxVoltageIn50mVunits);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_current = GUI_DECODE_10MA(pdo.SNKVariablePDO.OperationalCurrentIn10mAunits);
GUI_UPDATE_CURRENT_MAX(_current, _max_current);
break;
#if _PPS
case USBPD_CORE_PDO_TYPE_APDO: /*!< Augmented Power Data Object (APDO) */
_voltage = GUI_DECODE_100MV(pdo.SRCSNKAPDO.MinVoltageIn100mV);
GUI_UPDATE_VOLTAGE_MIN(_voltage, _min_voltage);
_voltage = GUI_DECODE_100MV(pdo.SRCSNKAPDO.MaxVoltageIn100mV);
GUI_UPDATE_VOLTAGE_MAX(_voltage, _max_voltage);
_current = GUI_DECODE_50MA(pdo.SRCSNKAPDO.MaxCurrentIn50mAunits);
GUI_UPDATE_CURRENT_MAX(_current, _max_current);
break;
#endif /*_USBPD_REV30_SUPPORT && PPS*/
default:
break;
}
}
GUI_CHECK_VOLTAGE_MIN(_min_voltage, DPM_USER_Settings[USBPD_PORT_1].DPM_SNKRequestedPower.MinOperatingVoltageInmVunits);
GUI_CHECK_VOLTAGE_MAX(_max_voltage, DPM_USER_Settings[USBPD_PORT_1].DPM_SNKRequestedPower.MaxOperatingVoltageInmVunits);
GUI_CHECK_CURRENT_MAX(_max_current, DPM_USER_Settings[USBPD_PORT_1].DPM_SNKRequestedPower.MaxOperatingCurrentInmAunits);
_max_power = (_max_voltage * _max_current) / 1000;
GUI_CHECK_POWER_MAX(_max_power, DPM_USER_Settings[USBPD_PORT_1].DPM_SNKRequestedPower.MaxOperatingPowerInmWunits);
}
#endif /* USBPD_PORT_COUNT==2 */
#endif /* _SNK) || _DRP */
/**
* @}
*/
/**
* @}
*/
#endif /* _GUI_INTERFACE */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/