3配置項(xiàng)目
在Project Manager主選項(xiàng)卡下,將Project選項(xiàng)卡下的最小堆棧大小配置為 0xC00 。這是第一個值,以后可以根據(jù)應(yīng)用需要進(jìn)行調(diào)整。
在Advanced Settings選項(xiàng)卡下,將 LPUART 驅(qū)動程序更改為 LL 以節(jié)省一點(diǎn)內(nèi)存堆大小。由于我們不需要 ADC 和 I2C 初始化函數(shù)(由 BSP 驅(qū)動程序處理),因此取消選中MX_I2C2_Init 和 MX_ADC1_Init 函數(shù)的 生成代碼 。
4將BSP添加到項(xiàng)目中
需要將 X-NUCLEO-SRC1M1 擴(kuò)展板的5 分鐘板級支持包 (BSP) 添加到項(xiàng)目中。這些文件需要手動復(fù)制到項(xiàng)目的文件夾中。從 GitHub x-cube-tcpp
獲取最新的 BSP 。
手動復(fù)制以下三個文件夾:
進(jìn)入:
然后,在項(xiàng)目的根文件夾中創(chuàng)建一個名為“ .extSettings ”的文件(請注意文件名中的點(diǎn)字符)并用以下代碼填充它:
該文件用于告訴代碼生成器在生成項(xiàng)目時(shí)包含 BSP 文件。
5生成代碼
使用 Ctrl+s 保存文件,并在出現(xiàn)提示時(shí)選擇生成代碼。您還可以通過單擊項(xiàng)目/生成代碼或按 Alt+K 從 STM32CubeIDE 菜單生成代碼。
出現(xiàn)一條警告,通知未定義正確的 HAL 時(shí)基。使用專用定時(shí)器作為 HAL 時(shí)基源更安全。
對于此演示,可以通過單擊是忽略以下警告。
信息 |
---|
這成為在即將發(fā)布的固件包交付中推薦的標(biāo)準(zhǔn)工作方式,尤其是在使用 CMSIS OS V2 時(shí),它將 Systick 定義為 FreeRTOS? 時(shí)基。對于此演示,可以通過單擊是忽略警告。 |
在這個項(xiàng)目中,可以找到不同的文件夾:
- USBPD文件夾包含我們需要編輯以豐富 Power Delivery 應(yīng)用程序的源文件。
- Core文件夾包含項(xiàng)目核心的源文件。
- Drivers文件夾包含 STM32的HAL 驅(qū)動程序,以及 Nucleo 板和 X-NUCLEO-SRC1M1 擴(kuò)展板的 BSP。
- Middleware文件夾包含 FreeRTOS? 和 USB-PD的源文件和庫。
- Utilities文件夾包含 GUI(UCPD 監(jiān)視器)和跟蹤器嵌入式源文件部分。
項(xiàng)目的 Explorer 視圖中的Drivers文件夾必須包含之前添加的 BSP 文件夾。
6完整的USB-PD應(yīng)用
Now that the peripherals are initialized by STM32CubeMX, some minimum level of the application needs to be added:
- src1m1_conf.h file needs to be created from its template, and added to the project
- User code needs to be added in several files
6.1 Add SRC1M1 configuration file
In the Drivers\\BSP\\X-NUCLEO-SRC1M1 folder you will find src1m1_conf_template.h . Copy it to Core\\Inc folder, and rename it src1m1_conf.h . It is the configuration file used for the X-NUCLEO-SRC1M1 BSP.
6.2 Modification in stm32g0xx_it.c
|
在/ USER CODE BEGIN-END Includes / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始包括 */
#include "src1m1_conf.h"
/* 用戶代碼結(jié)束包括 */
在/ USER CODE BEGIN-END 1 / 標(biāo)簽之間添加以下代碼:
/* USER CODE BEGIN 1 */
#if defined(TCPP0203_SUPPORT)
/**
* @brief 該函數(shù)處理外線 4_15 中斷請求。
*(在 TCPP0203 管理的情況下關(guān)聯(lián)到 FLGn 線)
* @retval None
*/
void TCPP0203_PORT0_FLG_EXTI_IRQHANDLER ( void )
{
/* 管理標(biāo)志 */
if ( TCPP0203_PORT0_FLG_EXTI_IS_ACTIVE_FLAG () != RESET )
{
/* 調(diào)用 BSP USBPD PWR 回調(diào) */
BSP_USBPD_CPWR_CWR_R ( USBPD_PWR_TYPE_C_PORT_1 );
/* 清除標(biāo)志 */
TCPP0203_PORT0_FLG_EXTI_CLEAR_FLAG ();
}
}
#endif /* TCPP0203_SUPPORT */
/* 用戶代碼結(jié)束 1 */
6.3 usbpd_dpm_user.h中的修改
在/ USER CODE BEGIN-END Typedef / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始 Typedef */
typedef struct
{
uint32_t DPM_ListOfRcvSNKPDO [ USBPD_MAX_NB_PDO ]; /*!< 從端口伙伴接收到的接收器功率數(shù)據(jù)對象列表
(當(dāng)端口伙伴是接收器或 DRP 端口時(shí))。*/
uint32_t DPM_NumberOfRcvSNKPDO ; /*!< 從端口伙伴接收到的接收器功率數(shù)據(jù)對象的數(shù)量
(當(dāng)端口伙伴是接收器或 DRP 端口時(shí))。
此參數(shù)必須設(shè)置為低于
USBPD_MAX_NB_PDO */
uint32_t DPM_RDOPosition ; /*!< 請求的 DO 在功能源列表中的 RDO 位置 */
uint32_t DPM_RDOPositionPrevious ; /*!< RDO 所請求 DO 在功能源列表中的位置 */
uint32_t DPM_RequestedVoltage ; /*!< 請求電壓值 */
uint32_t DPM_RequestedCurrent ; /*!< 請求電流值 */
uint32_t DPM_RcvRequestDOMsg ;
uint32_t DPM_RequestDOMsg ; /*!< 要發(fā)送的請求功率數(shù)據(jù)對象消息 */
uint32_t DPM_RequestDOMsgPrevious ; /*!< 要發(fā)送的上一個請求電源數(shù)據(jù)對象消息 */
} USBPD_HandleTypeDef ;
/* 用戶代碼結(jié)束類型定義 */
在/ USER CODE BEGIN-END Private_Variables / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始 Private_Variables */
extern USBPD_HandleTypeDef DPM_Ports [ USBPD_PORT_COUNT ];
/* 用戶代碼結(jié)束 Private_Variables */
6.4 usbpd_pdo_defs.h中的修改
在/ USER CODE BEGIN-END typedef / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始 typedef */
/**
* @brief USBPD 端口 PDO 結(jié)構(gòu)定義
*/
typedef struct
{
uint32_t * ListOfPDO ; /*!< Power 數(shù)據(jù)對象列表上的指針,定義
端口功能 */
uint8_t * NumberOfPDO ; /*!< ListOfPDO 中定義的電源數(shù)據(jù)對象的數(shù)量
此參數(shù)必須設(shè)置為最大值 @ref USBPD_MAX_NB_PDO 值 */
} USBPD_PortPDO_TypeDef ;
/**
* @brief USBPD 端口 PDO 存儲結(jié)構(gòu)定義
*/
typedef struct
{
USBPD_PortPDO_TypeDef SourcePDO ; /*!< SRC 電源數(shù)據(jù)對象 */
} USBPD_PWR_Port_PDO_Storage_TypeDef ;
/* 用戶代碼結(jié)束 typedef */
6.5 usbpd_pwr_if.c中的修改
在/ USER CODE BEGIN-END Private_Variables / 標(biāo)簽之間添加以下代碼:
/* USER CODE BEGIN Private_Variables */
/**
* @brief USBPD Port PDO Storage 數(shù)組聲明
*/
USBPD_PWR_Port_PDO_Storage_TypeDef PWR_Port_PDO_Storage [ USBPD_PORT_COUNT ];
/* 用戶代碼結(jié)束 Private_Variables */
在/ USER CODE BEGIN-END USBPD_PWR_IF_Init / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始 USBPD_PWR_IF_Init */
USBPD_StatusTypeDef _status = USBPD_OK ;
/* 設(shè)置指向 PDO 值和端口 0 號的鏈接(在 H 文件的 PDO 數(shù)組中定義)。*/
PWR_Port_PDO_Storage [ USBPD_PORT_0 ]。來源 PDO 。ListOfPDO = ( uint32_t * ) PORT0_PDO_ListSRC ;
PWR_Port_PDO_Storage [ USBPD_PORT_0 ]。來源 PDO 。NumberOfPDO = & USBPD_NbPDO [ 1 ];
返回 _狀態(tài);
/* 用戶代碼結(jié)束 USBPD_PWR_IF_Init */
在/ USER CODE BEGIN-END USBPD_PWR_IF_SetProfile / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始 USBPD_PWR_IF_SetProfile */
USBPD_PDO_TypeDef _pdo ;
USBPD_SNKRDO_TypeDef _rdo ;
_rdo 。d32 = DPM_Ports [端口號]。DPM_RcvRequestDOMsg ;
_pdo 。d32 = PORT0_PDO_ListSRC [ 0 ];
返回 (bsp_error_none == bsp_usbpd_pwr_vbussetvoltage_fixed (portnum ,
_pdo。srcfixedpdo。voltagein50mvunits * 50 ,(_ rdo.rdo。_rdo。_rdo。fixiaiablerdo.firedvariablerdo.promertin10MANITS * 10 )_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /* 用戶代碼結(jié)束 USBPD_PWR_IF_SetProfile */
在/ USER CODE BEGIN-END USBPD_PWR_IF_GetPortPDOs / 標(biāo)簽之間添加以下代碼:
/* 用戶代碼開始 USBPD_PWR_IF_GetPortPDOs */
uint32_t nbpdo , index , nb_valid_pdo = 0 ;
uint32_t * ptpdoarray = NULL ;
USBPD_PDO_TypeDef pdo_first ;
USBPD_PDO_TypeDef pdo ;
/* Check if valid port */
if (USBPD_PORT_IsValid(PortNum))
{
/* According to the type of PDO to be read, set the pointer on values and number of elements */
switch(DataId)
{
case USBPD_CORE_DATATYPE_SRC_PDO :
nbpdo = *PWR_Port_PDO_Storage[PortNum].SourcePDO.NumberOfPDO;
ptpdoarray = PWR_Port_PDO_Storage[PortNum].SourcePDO.ListOfPDO;
/* Save the 1st PDO */
pdo_first.d32 = *ptpdoarray;
/* Reset un-chunked bit if current revision is PD2.0*/
if (USBPD_SPECIFICATION_REV2 == DPM_Params[PortNum].PE_SpecRevision)
{
pdo_first.SRCFixedPDO.UnchunkedExtendedMessage = USBPD_PDO_SRC_FIXED_UNCHUNK_NOT_SUPPORTED;
}
break;
default :
nbpdo = 0;
break;
}
/* Copy PDO data in output buffer */
for (index = 0; index < nbpdo; index++)
{
pdo.d32 = *ptpdoarray;
/* Copy only PDO (and not APDO in case of current revision is PD2.0) */
if ((USBPD_SPECIFICATION_REV2 == DPM_Params[PortNum].PE_SpecRevision)
&& (pdo.GenericPDO.PowerObject == USBPD_CORE_PDO_TYPE_APDO))
{
}
else
{
/* Copy 1st PDO as potentially FRS or UNCHUNKED bits have been reset */
if (0 == index)
{
(void)memcpy(Ptr, (uint8_t*)&pdo_first.d32, 4u);
}
else
{
(void)memcpy((Ptr + (nb_valid_pdo * 4u)), (uint8_t*)ptpdoarray, 4u);
}
nb_valid_pdo++;
}
ptpdoarray++;
}
/* Set the number of read PDO (number of u32 elements); */
*Size = nb_valid_pdo;
}
/* USER CODE END USBPD_PWR_IF_GetPortPDOs */
Add the following code between the / USER CODE BEGIN-END USBPD_PWR_IF_SearchRequestedPDO / tags:
/* USER CODE BEGIN USBPD_PWR_IF_SearchRequestedPDO */
if((RdoPosition == 0) || (RdoPosition > *PWR_Port_PDO_Storage[PortNum].SourcePDO.NumberOfPDO))
{
/* Invalid PDO index */
return USBPD_FAIL;
}
*Pdo = PWR_Port_PDO_Storage[PortNum].SourcePDO.ListOfPDO[RdoPosition - 1];
return USBPD_OK;
/* USER CODE END USBPD_PWR_IF_SearchRequestedPDO */
6.6 Modification in usbpd_dpm_user.c
Add the following code between the / USER CODE BEGIN-END Private_Variables / tags:
/* USER CODE BEGIN Private_Variables */
USBPD_HandleTypeDef DPM_Ports[USBPD_PORT_COUNT];
/* USER CODE END Private_Variables */
Add the following code between the / USER CODE BEGIN-END USBPD_USER_PRIVATE_FUNCTIONS_Prototypes / tags:
/* USER CODE BEGIN USBPD_USER_PRIVATE_FUNCTIONS_Prototypes */
static USBPD_StatusTypeDef DPM_TurnOnPower(uint8_t PortNum, USBPD_PortPowerRole_TypeDef Role);
static USBPD_StatusTypeDef DPM_TurnOffPower(uint8_t PortNum, USBPD_PortPowerRole_TypeDef Role);
/* USER CODE END USBPD_USER_PRIVATE_FUNCTIONS_Prototypes */
Add the following code between the / USER CODE BEGIN-END USBPD_DPM_UserInit / tags:
/* USER CODE BEGIN USBPD_DPM_UserInit */
/* PWR SET UP */
if(USBPD_OK != USBPD_PWR_IF_Init())
{
return USBPD_ERROR;
}
return USBPD_OK;
/* USER CODE END USBPD_DPM_UserInit */
Add the following code between the / USER CODE BEGIN-END USBPD_DPM_UserCableDetection / tags:
/* USER CODE BEGIN USBPD_DPM_UserCableDetection */
switch(State)
{
case USBPD_CAD_EVENT_ATTACHED:
case USBPD_CAD_EVENT_ATTEMC:
{
if (DPM_Params[PortNum].PE_PowerRole == USBPD_PORTPOWERROLE_SRC)
{
if (USBPD_OK != USBPD_PWR_IF_VBUSEnable(PortNum))
{
/* Should not occur */
osDelay(6000);
NVIC_SystemReset();
}
}
break;
}
case USBPD_CAD_EVENT_DETACHED :
case USBPD_CAD_EVENT_EMC :
default :
{
if (DPM_Params[PortNum].PE_PowerRole == USBPD_PORTPOWERROLE_SRC)
{
if (USBPD_OK != USBPD_PWR_IF_VBUSDisable(PortNum))
{
/* Should not occur */
while(1);
}
}
break;
}
}
/* USER CODE END USBPD_DPM_UserCableDetection */
Add the following code between the / USER CODE BEGIN-END USBPD_DPM_HardReset / tags:
/* USER CODE BEGIN USBPD_DPM_HardReset */
switch (Status)
{
case USBPD_HR_STATUS_WAIT_VBUS_VSAFE0V:
if (USBPD_PORTPOWERROLE_SRC == CurrentRole)
{
/* Reset the power supply */
DPM_TurnOffPower(PortNum, USBPD_PORTPOWERROLE_SRC);
}
break;
case USBPD_HR_STATUS_WAIT_VBUS_VSAFE5V:
if (CurrentRole == USBPD_PORTPOWERROLE_SRC)
{
/* Power on the power supply */
DPM_TurnOnPower(PortNum, CurrentRole);
}
break;
default:
break;
}
/* USER CODE END USBPD_DPM_HardReset */
Add the following code between the / USER CODE BEGIN-END USBPD_DPM_GetDataInfo / tags:
/* USER CODE BEGIN USBPD_DPM_GetDataInfo */
/* Check type of information targeted by request */
switch(DataId)
{
case USBPD_CORE_DATATYPE_REQ_VOLTAGE: /*!< Get voltage value requested for BIST tests, expect 5V */
*Size = 4;
(void)memcpy((uint8_t*)Ptr, (uint8_t *)&DPM_Ports[PortNum].DPM_RequestedVoltage, *Size);
break;
case USBPD_CORE_DATATYPE_SRC_PDO: /*!< Handling of port Source PDO */
USBPD_PWR_IF_GetPortPDOs(PortNum, DataId, Ptr, Size);
*Size *= 4;
break;
// case USBPD_CORE_PPS_STATUS: /*!< PPS Status message content */
// break;
// case USBPD_CORE_SNK_EXTENDED_CAPA: /*!< Retrieve of Sink Extended capability message content */
// break;
// case USBPD_CORE_INFO_STATUS: /*!< Information status message content */
// break;
// case USBPD_CORE_MANUFACTURER_INFO: /*!< Retrieve of Manufacturer info message content */
// break;
// case USBPD_CORE_BATTERY_STATUS: /*!< Retrieve of Battery status message content */
// break;
// case USBPD_CORE_BATTERY_CAPABILITY: /*!< Retrieve of Battery capability message content */
// break;
default:
DPM_USER_DEBUG_TRACE(PortNum, "ADVICE: update USBPD_DPM_GetDataInfo:%d", DataId);
break;
}
/* USER CODE END USBPD_DPM_GetDataInfo */
Add the following code between the / USER CODE BEGIN-END USBPD_DPM_SetDataInfo / tags:
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
/* Check type of information targeted by request */
switch(DataId)
{
case USBPD_CORE_DATATYPE_RDO_POSITION: /*!< Reset the PDO position selected by the sink only */
if (Size == 4)
{
uint8_t* temp;
temp = (uint8_t*)&DPM_Ports[PortNum].DPM_RDOPosition;
(void)memcpy(temp, Ptr, Size);
DPM_Ports[PortNum].DPM_RDOPositionPrevious = *Ptr;
temp = (uint8_t*)&DPM_Ports[PortNum].DPM_RDOPositionPrevious;
(void)memcpy(temp, Ptr, Size);
}
break;
// case USBPD_CORE_DATATYPE_RCV_SRC_PDO: /*!< Storage of Received Source PDO values */
// break;
// case USBPD_CORE_DATATYPE_RCV_SNK_PDO: /*!< Storage of Received Sink PDO values */
// break;
case USBPD_CORE_DATATYPE_RCV_REQ_PDO : /*!< Storage of Received Sink Request PDO value */
if (Size == 4)
{
memcpy((uint8_t *)&DPM_Ports[PortNum].DPM_RcvRequestDOMsg, Ptr, 4);
}
break;
// case USBPD_CORE_INFO_STATUS: /*!< Information status message content */
// break;
// case USBPD_CORE_ALERT: /*!< Storing of received Alert message content */
// break;
// case USBPD_CORE_GET_MANUFACTURER_INFO: /*!< Storing of received Get Manufacturer info message content */
// break;
// case USBPD_CORE_GET_BATTERY_STATUS: /*!< Storing of received Get Battery status message content */
// break;
// case USBPD_CORE_GET_BATTERY_CAPABILITY: /*!< Storing of received Get Battery capability message content*/
// break;
// case USBPD_CORE_SNK_EXTENDED_CAPA: /*!< Storing of Sink Extended capability message content */
// break;
default:
DPM_USER_DEBUG_TRACE(PortNum, "ADVICE: update USBPD_DPM_SetDataInfo:%d", DataId);
break;
}
/* USER CODE END USBPD_DPM_SetDataInfo */
Add the following code between the / USER CODE BEGIN-END USBPD_DPM_EvaluateRequest / tags:
/* USER CODE BEGIN USBPD_DPM_EvaluateRequest */
USBPD_StatusTypeDef _retr = USBPD_REJECT;
USBPD_PDO_TypeDef pdo;
USBPD_SNKRDO_TypeDef rdo;
/* read the request value received */
rdo.d32 = DPM_Ports[PortNum].DPM_RcvRequestDOMsg;
/* Search PDO in Port Source PDO list, that corresponds to Position provided in Request RDO */
if (USBPD_PWR_IF_SearchRequestedPDO(PortNum, rdo.GenericRDO.ObjectPosition, &pdo.d32) == USBPD_OK)
{
/* Evaluate the request */
if(pdo.GenericPDO.PowerObject == USBPD_CORE_PDO_TYPE_FIXED)
{
if((rdo.FixedVariableRDO.OperatingCurrentIn10mAunits > pdo.SRCFixedPDO.MaxCurrentIn10mAunits)
|| (rdo.FixedVariableRDO.MaxOperatingCurrent10mAunits > pdo.SRCFixedPDO.MaxCurrentIn10mAunits))
{
/* Sink requests too much maximum operating current */
/* USBPD_DPM_EvaluateRequest: Sink requests too much maximum operating current */
_retr = USBPD_REJECT;
}
else
{
/* Save the power object */
*PtrPowerObject = pdo.GenericPDO.PowerObject;
/* Set RDO position and requested voltage in DPM port structure */
DPM_Ports[PortNum].DPM_RequestedVoltage = pdo.SRCFixedPDO.VoltageIn50mVunits * 50;
DPM_Ports[PortNum].DPM_RDOPositionPrevious = DPM_Ports[PortNum].DPM_RDOPosition;
DPM_Ports[PortNum].DPM_RDOPosition = rdo.GenericRDO.ObjectPosition;
_retr = USBPD_ACCEPT;
}
}
}
return _retr;
/* USER CODE END USBPD_DPM_EvaluateRequest */
Add the following code between the / USER CODE BEGIN-END USBPD_USER_PRIVATE_FUNCTIONS / tags:
/* USER CODE BEGIN USBPD_USER_PRIVATE_FUNCTIONS */
/**
* @brief Turn Off power supply.
* @param PortNum The current port number
* @param Role Port power role
* @retval USBPD_OK, USBPD_ERROR
*/
static USBPD_StatusTypeDef DPM_TurnOffPower(uint8_t PortNum, USBPD_PortPowerRole_TypeDef Role)
{
USBPD_StatusTypeDef status;
status = USBPD_PWR_IF_VBUSDisable(PortNum);
return status;
}
/**
* @brief Turn On power supply.
* @param PortNum The current port number
* @param Role Port power role
* @retval USBPD_ACCEPT, USBPD_WAIT, USBPD_REJECT
*/
static USBPD_StatusTypeDef DPM_TurnOnPower(uint8_t PortNum, USBPD_PortPowerRole_TypeDef Role)
{
USBPD_StatusTypeDef status;
/* Enable the output */
status = USBPD_PWR_IF_VBUSEnable(PortNum);
return status;
}
/* USER CODE END USBPD_USER_PRIVATE_FUNCTIONS */
-
usb
+關(guān)注
關(guān)注
60文章
7879瀏覽量
263728 -
PD
+關(guān)注
關(guān)注
4文章
458瀏覽量
43889
發(fā)布評論請先 登錄
相關(guān)推薦
評論