Files
IronOS/source/Core/Threads/POWThread.cpp
2025-07-17 19:37:49 +10:00

76 lines
2.1 KiB
C++

/*
* POWThread.cpp
*
* Created on: 16 Jan 2021
* Author: Ralim
*/
#include "BSP.h"
#include "FS2711.hpp"
#include "FreeRTOS.h"
#include "HUB238.hpp"
#include "QC3.h"
#include "Settings.h"
#include "USBPD.h"
#include "cmsis_os.h"
#include "configuration.h"
#include "main.hpp"
#include "stdbool.h"
#include "stdlib.h"
#include "task.h"
// Small worker thread to handle power (PD + QC) related steps
void startPOWTask(void const *argument __unused) {
bool haveNegotiatedHigherPower = false;
// Init any other misc sensors
postRToSInit();
// You have to run this once we are willing to answer PD messages
// Setting up too early can mean that we miss the ~20ms window to respond on some chargers
#ifdef POW_PD
USBPowerDelivery::start();
// Crank the handle at boot until we are stable and waiting for IRQ
USBPowerDelivery::step();
#endif
#if POW_PD_EXT == 2
FS2711::start();
#endif
BaseType_t res;
for (;;) {
res = pdFALSE;
// While the interrupt is low, dont delay
/*This is due to a possible race condition, where:
* IRQ fires
* We read interrupt register but dont see the Good CRC
* Then Good CRC is set while reading it out (racing on I2C read)
* Then we would sleep as nothing to do, but 100ms> 20ms power supply typical timeout
*/
if (!getFUS302IRQLow()) {
res = xTaskNotifyWait(0x0, 0xFFFFFF, NULL, TICKS_100MS / 2);
}
#ifdef POW_PD
if (res != pdFALSE || getFUS302IRQLow()) {
USBPowerDelivery::IRQOccured();
}
USBPowerDelivery::PPSTimerCallback();
USBPowerDelivery::step();
// Once tip measurement is done, and we have done the basic negotiation, we want to do the higher voltage negotiation steps
if (tipMeasurementDone() == 1 && !haveNegotiatedHigherPower) {
USBPowerDelivery::reNegotiate();
}
#else
(void)res;
#endif
#if POW_PD_EXT == 1
hub238_check_negotiation();
#endif
#if POW_PD_EXT == 2
if (tipMeasurementDone() == 1) {
FS2711::negotiate();
}
#endif
power_check();
}
}