/* 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****/