if (port->PpsEnabled && PPSAPDO) { /* Req current (50mA units) and voltage (20mV units) */ port->SinkRequest.PPSRDO.ObjectPosition = PPSAPDO; if (port->SrcCapsReceived[PPSAPDO - 1].PPSAPDO.MaxCurrent >= DPM_GetSinkCap(port->dpm, port)[PPSRDO].PPSAPDO.MaxCurrent) port->SinkRequest.PPSRDO.OpCurrent = DPM_GetSinkCap(port->dpm, port)[PPSRDO].PPSAPDO.MaxCurrent; else port->SinkRequest.PPSRDO.OpCurrent = port->SrcCapsReceived[PPSAPDO - 1].PPSAPDO.MaxCurrent; port->SinkRequest.PPSRDO.Voltage = DPM_GetSinkCap(port->dpm, port)[PPSRDO]. PPSAPDO.MinVoltage * 5; }代码分析
时间: 2024-04-04 15:29:13 浏览: 18
这段代码实现的是如果一个端口的 PPS(Programmable Power Supply) 功能已经启用,并且 PPSAPDO(PPS Alternate Mode Object)不为 NULL,那么会向 Sink 发送请求获取当前的电压和电流。具体的实现如下:
- 首先,设置端口的 SinkRequest.PPSRDO.ObjectPosition 为 PPSAPDO。
- 然后,判断 PPSAPDO 对应的 SrcCapsReceived 中的最大电流是否大于等于当前 Sink 的最大电流,如果是,则将 SinkRequest.PPSRDO.OpCurrent 设置为当前 Sink 的最大电流,否则设置为 PPSAPDO 对应的 SrcCapsReceived 中的最大电流。
- 最后,将 SinkRequest.PPSRDO.Voltage 设置为当前 Sink 的最小电压乘以 5。
这段代码主要是用于实现 USB-PD 协议中的 PPS 功能,根据不同的电源和设备需求,可以动态调整电流和电压,从而实现更为高效的充电。
相关问题
void PolicySinkSelectCapability(Port_t *port) { /* AW_LOG("enter PolicySubIndex = %d\n", port->PolicySubIndex); */ switch (port->PolicySubIndex) { case 0: if (PolicySendData(port, DMTRequest, &port->SinkRequest, sizeof(doDataObject_t), peSinkSelectCapability, 1, SOP_TYPE_SOP, AW_FALSE) == STAT_SUCCESS) { TimerStart(&port->PolicyStateTimer, tSenderResponse); port->WaitingOnHR = AW_TRUE; } break; case 1: if (port->ProtocolMsgRx) { port->ProtocolMsgRx = AW_FALSE; if (port->PolicyRxHeader.NumDataObjects == 0) { switch (port->PolicyRxHeader.MessageType) { case CMTAccept: /* Check if PPS was selected (Here as well, for GUI req) */ port->PpsEnabled = (port->SrcCapsReceived[port->SinkRequest.FVRDO.ObjectPosition - 1].PDO.SupplyType == pdoTypeAugmented) ? AW_TRUE : AW_FALSE; port->PolicyHasContract = AW_TRUE; port->USBPDContract.object = port->SinkRequest.object; TimerStart(&port->PolicyStateTimer, tPSTransition); SetPEState(port, peSinkTransitionSink); if (port->PpsEnabled == AW_TRUE) TimerStart(&port->PpsTimer, tPPSRequest); break; case CMTWait: case CMTReject: if (port->PolicyHasContract) SetPEState(port, peSinkReady); else { SetPEState(port, peSinkWaitCaps); /* Make sure we don't send reset to prevent loop */ port->HardResetCounter = nHardResetCount + 1; } break; case CMTSoftReset: SetPEState(port, peSinkSoftReset); break; default: SetPEState(port, peSinkSendSoftReset); break; } } else { switch (port->PolicyRxHeader.MessageType) { case DMTSourceCapabilities: UpdateCapabilitiesRx(port, AW_TRUE); SetPEState(port, peSinkEvaluateCaps); break; default: SetPEState(port, peSinkSendSoftReset); break; } } } else if (TimerExpired(&port->PolicyStateTimer)) { SetPEState(port, peSinkSendHardReset); } else { port->PEIdle = AW_TRUE; } break; } }代码分析
这是一个函数,函数名称为PolicySinkSelectCapability,其参数为指向Port_t类型的指针port。
该函数的作用是选择Sink的能力并发送请求。
函数采用switch语句根据port->PolicySubIndex的值来进行不同的操作。当PolicySubIndex为0时,函数会调用PolicySendData函数发送一个DMTRequest类型的请求,并启动定时器TimerStart。当PolicySubIndex为1时,函数会判断port->ProtocolMsgRx的值,如果为真,则进行一系列的判断,根据接收到的消息类型进行不同的操作;如果为假,则判断定时器TimerExpired的值,如果为真,则调用SetPEState函数设置电源协商状态,并进行相应的操作;否则,将port->PEIdle的值设置为真。
在具体的操作中,当接收到的消息类型为CMTAccept时,会设置port->PpsEnabled的值,并启动定时器TimerStart;当接收到的消息类型为CMTWait或CMTReject时,如果已经有合同,则设置电源协商状态为peSinkReady;否则,设置电源协商状态为peSinkWaitCaps,并将port->HardResetCounter的值设置为nHardResetCount + 1;当接收到的消息类型为CMTSoftReset时,设置电源协商状态为peSinkSoftReset;否则,设置电源协商状态为peSinkSendSoftReset。
当接收到的消息类型为DMTSourceCapabilities时,调用UpdateCapabilitiesRx函数更新接收到的能力,并设置电源协商状态为peSinkEvaluateCaps;否则,设置电源协商状态为peSinkSendSoftReset。
if(req->priv != NULL) { *pHWResource = *((sd_Device_HWResource *) req->priv); }
这段代码是一个条件语句,首先判断 `req->priv` 是否为非空(即不为 NULL)。如果 `req->priv` 不为空,则进入条件语句的代码块。
在条件语句的代码块中,`*pHWResource = *((sd_Device_HWResource *) req->priv);` 这行代码将 `req->priv` 转换为 `sd_Device_HWResource` 类型的指针,并将其解引用赋值给 `*pHWResource`。
换句话说,如果 `req->priv` 不为空,那么将 `req->priv` 转换为 `sd_Device_HWResource` 类型的指针,并将其所指向的值赋给 `pHWResource` 所指向的变量。