/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usbpd.c
* @author MCD Application Team
* @brief This file contains the device define.
******************************************************************************
* @attention
*
*
© Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbpd.h"
/* USER CODE BEGIN 0 */
#include "usbpd_core.h"
#include "usbpd_dpm_core.h"
#include "usbpd_dpm_conf.h"
#include "usbpd_dpm_user.h"
#include "usbpd_pwr_if.h"
#include "battery.h"
#include "bq25703a_regulator.h"
#include "printf.h"
#include
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* Global variables ---------------------------------------------------------*/
/* USER CODE BEGIN 2 */
/* Private typedef -----------------------------------------------------------*/
struct USB_PD_Received_Source_PDO {
uint32_t voltage_mv;
uint32_t current_ma;
uint32_t power_mw;
};
/* Private variables ---------------------------------------------------------*/
volatile struct USB_PD_Received_Source_PDO source_pdo[USBPD_MAX_NB_PDO];
volatile uint32_t max_source_power_mw = 0;
volatile uint8_t max_source_power_pdo = 0;
volatile uint8_t selected_source_pdo = 0;
volatile uint8_t power_ready = NOT_READY;
volatile uint8_t match_found = 0;
volatile uint16_t voltage_choice_list_mv[3][VOLTAGE_CHOICE_ARRAY_SIZE] = {
{9000, 12000, 15000, 5000, 20000}, //Two S voltage choice list
{12000, 15000, 20000, 9000, 5000}, //Three S voltage choice list
{20000, 15000, 12000, 9000, 5000} //Four S voltage choice list
};
osMessageQId USBPDMsgBox;
osThreadId USBPD_User_TaskHandle;
void vUSBPD_User(void const *pvParameters);
uint8_t check_if_power_ready(void);
/* USER CODE END 2 */
/* USBPD init function */
void MX_USBPD_Init(void)
{
/* Global Init of USBPD HW */
USBPD_HW_IF_GlobalHwInit();
/* Initialize the Device Policy Manager */
if(USBPD_OK != USBPD_DPM_InitCore())
{
while(1);
}
/* Initialise the DPM application */
if (USBPD_OK != USBPD_DPM_UserInit())
{
while(1);
}
/* USER CODE BEGIN 3 */
osThreadDef(usbpd_user_app, vUSBPD_User, USBPD_TASK_PRIORITY, 0, configMINIMAL_STACK_SIZE);
USBPD_User_TaskHandle = osThreadCreate(osThread(usbpd_user_app), NULL);
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
/**
* @brief Gets the state of the input power supply
* @retval READY or NOT_READY
*/
uint8_t Get_Input_Power_Ready(void) {
return power_ready;
}
/**
* @brief Gets the max input power for the selected PDO
* @retval Max input power in mW
*/
uint32_t Get_Max_Input_Power(void){
return source_pdo[selected_source_pdo].power_mw;
}
/**
* @brief Gets the max input current for the selected PDO
* @retval Max input current in mA
*/
uint32_t Get_Max_Input_Current(void) {
return source_pdo[selected_source_pdo].current_ma;
}
/**
* @brief Gets the input voltage for the selected PDO
* @retval Input Voltage in mV
*/
uint32_t Get_Input_Voltage(void) {
return source_pdo[selected_source_pdo].voltage_mv;
}
void vUSBPD_User(void const *pvParameters) {
TickType_t xDelay = 500 / portTICK_PERIOD_MS;
USBPD_StatusTypeDef status = USBPD_ERROR;
vTaskDelay(xDelay);
/* while (status != USBPD_OK) {
//status = USBPD_DPM_RequestGetSourceCapability(USBPD_PORT_0);
//printf("USBPD_DPM_RequestGetSourceCapability Status: %d\r\n", status);
if (status == USBPD_ERROR) {
//printf("USBPD Error. Sending Hard Reset\r\n");
//USBPD_DPM_RequestHardReset(USBPD_PORT_0);
}
vTaskDelay(xDelay);
}
*/
printf("Number of received Source PDOs: %d\r\n", DPM_Ports[USBPD_PORT_0].DPM_NumberOfRcvSRCPDO);
USBPD_PDO_TypeDef srcpdo;
uint32_t nbsnkpdo;
uint32_t snkpdo_array[USBPD_MAX_NB_PDO];
USBPD_PWR_IF_GetPortPDOs(USBPD_PORT_0, USBPD_CORE_DATATYPE_SNK_PDO, (uint8_t*)snkpdo_array, &nbsnkpdo);
for (int i = 0; i < DPM_Ports[USBPD_PORT_0].DPM_NumberOfRcvSRCPDO; i++) {
printf("PDO From Source: #%d PDO: %d ", i, DPM_Ports[USBPD_PORT_0].DPM_ListOfRcvSRCPDO[i]);
srcpdo.d32 = DPM_Ports[USBPD_PORT_0].DPM_ListOfRcvSRCPDO[i];
switch(srcpdo.GenericPDO.PowerObject)
{
/* SRC Fixed Supply PDO */
case USBPD_CORE_PDO_TYPE_FIXED:
source_pdo[i].voltage_mv = (srcpdo.SRCFixedPDO.VoltageIn50mVunits * 50);
source_pdo[i].current_ma = (srcpdo.SRCFixedPDO.MaxCurrentIn10mAunits * 10);
source_pdo[i].power_mw = (source_pdo[i].current_ma * source_pdo[i].voltage_mv) / 1000;
if (source_pdo[i].power_mw > max_source_power_mw){
max_source_power_mw = source_pdo[i].power_mw;
max_source_power_pdo = i;
}
break;
// /* SRC Variable Supply (non-battery) PDO */
case USBPD_CORE_PDO_TYPE_VARIABLE:
printf("USBPD_CORE_PDO_TYPE_VARIABLE ");
// srcmaxvoltage50mv = srcpdo.SRCVariablePDO.MaxVoltageIn50mVunits;
// srcminvoltage50mv = srcpdo.SRCVariablePDO.MinVoltageIn50mVunits;
// srcmaxcurrent10ma = srcpdo.SRCVariablePDO.MaxCurrentIn10mAunits;
break;
// /* SRC Battery Supply PDO */
case USBPD_CORE_PDO_TYPE_BATTERY:
printf("USBPD_CORE_PDO_TYPE_BATTERY ");
// srcmaxvoltage50mv = srcpdo.SRCBatteryPDO.MaxVoltageIn50mVunits;
// srcminvoltage50mv = srcpdo.SRCBatteryPDO.MinVoltageIn50mVunits;
// srcmaxpower250mw = srcpdo.SRCBatteryPDO.MaxAllowablePowerIn250mWunits;
break;
// /* Augmented Power Data Object (APDO) */
case USBPD_CORE_PDO_TYPE_APDO:
printf("USBPD_CORE_PDO_TYPE_BATTERY ");
// srcmaxvoltage100mv = srcpdo.SRCSNKAPDO.MaxVoltageIn100mV;
// srcmaxcurrent50ma = srcpdo.SRCSNKAPDO.MaxCurrentIn50mAunits;
break;
default:
break;
}
printf("Voltage: %dmV Current: %dmA Power: %dmW\r\n", source_pdo[i].voltage_mv, source_pdo[i].current_ma, source_pdo[i].power_mw);
}
if (DPM_Ports[USBPD_PORT_0].DPM_NumberOfRcvSRCPDO == 0) {
power_ready = NO_USB_PD_SUPPLY;
for(;;) {
vTaskDelay(xDelay);
}
}
for (;;) {
//Find the best PDO from the source for the highest regulator efficiency
if ((Get_Balance_Connection_State() == CONNECTED)) {
if (match_found == 0) {
for (int i = 0; i < VOLTAGE_CHOICE_ARRAY_SIZE; i++) {
for (int t = 0; t < DPM_Ports[USBPD_PORT_0].DPM_NumberOfRcvSRCPDO; t++) {
if (voltage_choice_list_mv[Get_Number_Of_Cells() - 2][i] == source_pdo[t].voltage_mv) {
printf("Voltage match found: %d\r\n", source_pdo[t].voltage_mv);
selected_source_pdo = t;
match_found = 1;
break;
}
}
if (match_found != 0) {
break;
}
}
}
}
else {
match_found = 0;
}
if ((Get_XT60_Connection_State() == CONNECTED) && (Get_Balance_Connection_State() == CONNECTED) && (power_ready == NOT_READY) && (match_found == 1)) {
printf("Requesting %dV, Result: ", (source_pdo[selected_source_pdo].voltage_mv/1000));
status = USBPD_DPM_RequestMessageRequest(USBPD_PORT_0, (selected_source_pdo + 1), (uint16_t)source_pdo[selected_source_pdo].voltage_mv);
vTaskDelay(400 / portTICK_PERIOD_MS);
if (status == USBPD_OK) {
if (check_if_power_ready() != READY) {
printf("Waiting for input voltage to be ready\r\n");
power_ready = NOT_READY;
}
else {
printf("Success\r\n");
power_ready = READY;
}
}
else {
printf("Failed\r\n");
power_ready = NOT_READY;
}
}
else if ((Get_XT60_Connection_State() == NOT_CONNECTED) || (Get_Balance_Connection_State() == NOT_CONNECTED)){
if (Get_VBUS_ADC_Reading() > (6 * REG_ADC_MULTIPLIER)) {
printf("Requesting 5V, Result: ");
status = USBPD_DPM_RequestMessageRequest(USBPD_PORT_0, 1, (uint16_t)5000);
vTaskDelay(100 / portTICK_PERIOD_MS);
if (status == USBPD_OK) {
printf("Success\r\n");
}
else {
printf("Failed\r\n");
}
}
power_ready = NOT_READY;
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
vTaskDelay(xDelay);
}
}
/**
* @brief Compares the selected source PDO voltage to the measured input voltage
* @retval READY or NOT_READY
*/
uint8_t check_if_power_ready() {
if (Get_VBUS_ADC_Reading() > ((source_pdo[selected_source_pdo].voltage_mv * (REG_ADC_MULTIPLIER/1000)) - (2 * REG_ADC_MULTIPLIER))) {
return READY;
}
return NOT_READY;
}
/* USER CODE END 4 */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/