|
|
|
|
@@ -54,7 +54,7 @@ void PolicyEngine::init() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PolicyEngine::notify(PolicyEngine::Notifications notification) {
|
|
|
|
|
uint32_t val = (uint32_t)notification;
|
|
|
|
|
EventBits_t val = (EventBits_t)notification;
|
|
|
|
|
if (xEventGroupHandle != NULL) {
|
|
|
|
|
xEventGroupSetBits(xEventGroupHandle, val);
|
|
|
|
|
}
|
|
|
|
|
@@ -155,7 +155,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_discovery() {
|
|
|
|
|
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() {
|
|
|
|
|
/* Fetch a message from the protocol layer */
|
|
|
|
|
eventmask_t evt = 0;
|
|
|
|
|
EventBits_t evt = 0;
|
|
|
|
|
if (readMessage()) {
|
|
|
|
|
evt = (uint32_t)Notifications::PDB_EVT_PE_MSG_RX_PEND;
|
|
|
|
|
} else {
|
|
|
|
|
@@ -179,7 +179,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() {
|
|
|
|
|
/* If we got a message */
|
|
|
|
|
if (evt & ((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_MSG_RX_PEND)) {
|
|
|
|
|
/* Get the message */
|
|
|
|
|
while ((evt & (uint32_t)Notifications::PDB_EVT_PE_MSG_RX_PEND) || readMessage() == true) {
|
|
|
|
|
while (readMessage()) {
|
|
|
|
|
/* If we got a Source_Capabilities message, read it. */
|
|
|
|
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_SOURCE_CAPABILITIES && PD_NUMOBJ_GET(&tempMessage) > 0) {
|
|
|
|
|
/* First, determine what PD revision we're using */
|
|
|
|
|
@@ -195,15 +195,13 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_wait_cap() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return PESinkEvalCap;
|
|
|
|
|
/* If the message was a Soft_Reset, do the soft reset procedure */
|
|
|
|
|
}
|
|
|
|
|
evt = 0;
|
|
|
|
|
}
|
|
|
|
|
return PESinkWaitCap; // wait for more messages?
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we failed to get a message, send a hard reset */
|
|
|
|
|
return PESinkHardReset;
|
|
|
|
|
/* If we failed to get a message, wait longer */
|
|
|
|
|
return PESinkWaitCap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_eval_cap() {
|
|
|
|
|
@@ -229,10 +227,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_eval_cap() {
|
|
|
|
|
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
|
|
|
|
|
/* If the request was for a PPS APDO, start time callbacks if not started */
|
|
|
|
|
if (PD_RDO_OBJPOS_GET(&_last_dpm_request) >= _pps_index) {
|
|
|
|
|
if (PPSTimerEnabled == false) {
|
|
|
|
|
PPSTimerEnabled = true;
|
|
|
|
|
PPSTimeLastEvent = xTaskGetTickCount();
|
|
|
|
|
}
|
|
|
|
|
PPSTimerEnabled = true;
|
|
|
|
|
} else {
|
|
|
|
|
PPSTimerEnabled = false;
|
|
|
|
|
}
|
|
|
|
|
@@ -246,11 +241,10 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_eval_cap() {
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_select_cap() {
|
|
|
|
|
|
|
|
|
|
/* Transmit the request */
|
|
|
|
|
waitForEvent(0xFFFF, 0); // clear pending
|
|
|
|
|
waitForEvent((uint32_t)Notifications::PDB_EVT_PE_ALL, 0); // clear pending
|
|
|
|
|
ProtocolTransmit::pushMessage(&_last_dpm_request);
|
|
|
|
|
// Send indication that there is a message pending
|
|
|
|
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET || evt == 0) {
|
|
|
|
|
return PESinkTransitionDefault;
|
|
|
|
|
@@ -298,18 +292,19 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_select_cap() {
|
|
|
|
|
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_sink() {
|
|
|
|
|
/* Wait for the PS_RDY message */
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_PS_TRANSITION);
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
EventBits_t evt = 0;
|
|
|
|
|
|
|
|
|
|
if (messageWaiting()) {
|
|
|
|
|
evt = (uint32_t)Notifications::PDB_EVT_PE_MSG_RX;
|
|
|
|
|
} else {
|
|
|
|
|
evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_PS_TRANSITION);
|
|
|
|
|
} /* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) {
|
|
|
|
|
return PESinkTransitionDefault;
|
|
|
|
|
}
|
|
|
|
|
/* If no message was received, send a hard reset */
|
|
|
|
|
if (evt == 0) {
|
|
|
|
|
return PESinkSoftReset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we received a message, read it */
|
|
|
|
|
if (messageWaiting()) {
|
|
|
|
|
while (messageWaiting()) {
|
|
|
|
|
readMessage();
|
|
|
|
|
/* If we got a PS_RDY, handle it */
|
|
|
|
|
if (PD_MSGTYPE_GET(&tempMessage) == PD_MSGTYPE_PS_RDY && PD_NUMOBJ_GET(&tempMessage) == 0) {
|
|
|
|
|
@@ -321,22 +316,17 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_transition_sink() {
|
|
|
|
|
|
|
|
|
|
return PESinkReady;
|
|
|
|
|
/* If there was a protocol error, send a hard reset */
|
|
|
|
|
} else {
|
|
|
|
|
pdbs_dpm_transition_default();
|
|
|
|
|
return PESinkSoftReset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PESinkSoftReset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_ready() {
|
|
|
|
|
eventmask_t evt;
|
|
|
|
|
|
|
|
|
|
/* Wait for an event */
|
|
|
|
|
evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_MSG_RX | (uint32_t)Notifications::PDB_EVT_PE_RESET | (uint32_t)Notifications::PDB_EVT_PE_I_OVRTEMP
|
|
|
|
|
| (uint32_t)Notifications::PDB_EVT_PE_GET_SOURCE_CAP | (uint32_t)Notifications::PDB_EVT_PE_NEW_POWER | (uint32_t)Notifications::PDB_EVT_PE_PPS_REQUEST);
|
|
|
|
|
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_ALL);
|
|
|
|
|
/* If SinkPPSPeriodicTimer ran out, send a new request */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_PPS_REQUEST) {
|
|
|
|
|
return PESinkSelectCap;
|
|
|
|
|
}
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) {
|
|
|
|
|
return PESinkTransitionDefault;
|
|
|
|
|
@@ -358,10 +348,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_ready() {
|
|
|
|
|
/* Tell the protocol layer we're starting an AMS */
|
|
|
|
|
return PESinkEvalCap;
|
|
|
|
|
}
|
|
|
|
|
/* If SinkPPSPeriodicTimer ran out, send a new request */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_PPS_REQUEST) {
|
|
|
|
|
return PESinkSelectCap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we received a message */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_MSG_RX) {
|
|
|
|
|
if (messageWaiting()) {
|
|
|
|
|
@@ -419,9 +406,6 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_ready() {
|
|
|
|
|
|
|
|
|
|
return PESinkSendSoftReset;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* if we get an unknown message code, reset*/
|
|
|
|
|
return PESinkSendSoftReset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -436,8 +420,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_get_source_cap() {
|
|
|
|
|
get_source_cap->hdr = hdr_template | PD_MSGTYPE_GET_SOURCE_CAP | PD_NUMOBJ(0);
|
|
|
|
|
/* Transmit the Get_Source_Cap */
|
|
|
|
|
ProtocolTransmit::pushMessage(get_source_cap);
|
|
|
|
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
/* Free the sent message */
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) {
|
|
|
|
|
@@ -459,8 +442,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_give_sink_cap() {
|
|
|
|
|
|
|
|
|
|
/* Transmit our capabilities */
|
|
|
|
|
ProtocolTransmit::pushMessage(snk_cap);
|
|
|
|
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
|
|
|
|
|
/* Free the Sink_Capabilities message */
|
|
|
|
|
|
|
|
|
|
@@ -513,8 +495,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_soft_reset() {
|
|
|
|
|
accept.hdr = hdr_template | PD_MSGTYPE_ACCEPT | PD_NUMOBJ(0);
|
|
|
|
|
/* Transmit the Accept */
|
|
|
|
|
ProtocolTransmit::pushMessage(&accept);
|
|
|
|
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
/* Free the sent message */
|
|
|
|
|
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
@@ -539,8 +520,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_soft_reset() {
|
|
|
|
|
softrst->hdr = hdr_template | PD_MSGTYPE_SOFT_RESET | PD_NUMOBJ(0);
|
|
|
|
|
/* Transmit the soft reset */
|
|
|
|
|
ProtocolTransmit::pushMessage(softrst);
|
|
|
|
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) {
|
|
|
|
|
return PESinkTransitionDefault;
|
|
|
|
|
@@ -583,20 +563,18 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_soft_reset() {
|
|
|
|
|
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_not_supported() {
|
|
|
|
|
/* Get a message object */
|
|
|
|
|
union pd_msg *not_supported = &tempMessage;
|
|
|
|
|
|
|
|
|
|
if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_2_0) {
|
|
|
|
|
/* Make a Reject message */
|
|
|
|
|
not_supported->hdr = hdr_template | PD_MSGTYPE_REJECT | PD_NUMOBJ(0);
|
|
|
|
|
tempMessage.hdr = hdr_template | PD_MSGTYPE_REJECT | PD_NUMOBJ(0);
|
|
|
|
|
} else if ((hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
|
|
|
|
|
/* Make a Not_Supported message */
|
|
|
|
|
not_supported->hdr = hdr_template | PD_MSGTYPE_NOT_SUPPORTED | PD_NUMOBJ(0);
|
|
|
|
|
tempMessage.hdr = hdr_template | PD_MSGTYPE_NOT_SUPPORTED | PD_NUMOBJ(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Transmit the message */
|
|
|
|
|
ProtocolTransmit::pushMessage(not_supported);
|
|
|
|
|
ProtocolTransmit::notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX);
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
ProtocolTransmit::pushMessage(&tempMessage);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_TX_DONE | (uint32_t)Notifications::PDB_EVT_PE_TX_ERR | (uint32_t)Notifications::PDB_EVT_PE_RESET);
|
|
|
|
|
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) {
|
|
|
|
|
@@ -613,7 +591,7 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_send_not_supported() {
|
|
|
|
|
PolicyEngine::policy_engine_state PolicyEngine::pe_sink_chunk_received() {
|
|
|
|
|
|
|
|
|
|
/* Wait for tChunkingNotSupported */
|
|
|
|
|
eventmask_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_CHUNKING_NOT_SUPPORTED);
|
|
|
|
|
EventBits_t evt = waitForEvent((uint32_t)Notifications::PDB_EVT_PE_RESET, PD_T_CHUNKING_NOT_SUPPORTED);
|
|
|
|
|
/* If we got reset signaling, transition to default */
|
|
|
|
|
if (evt & (uint32_t)Notifications::PDB_EVT_PE_RESET) {
|
|
|
|
|
return PESinkTransitionDefault;
|
|
|
|
|
@@ -636,19 +614,18 @@ PolicyEngine::policy_engine_state PolicyEngine::pe_sink_source_unresponsive() {
|
|
|
|
|
return PESinkSourceUnresponsive;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t PolicyEngine::waitForEvent(uint32_t mask, TickType_t ticksToWait) { return xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE, ticksToWait); }
|
|
|
|
|
EventBits_t PolicyEngine::waitForEvent(uint32_t mask, TickType_t ticksToWait) { return xEventGroupWaitBits(xEventGroupHandle, mask, mask, pdFALSE, ticksToWait); }
|
|
|
|
|
|
|
|
|
|
bool PolicyEngine::isPD3_0() { return (hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0; }
|
|
|
|
|
|
|
|
|
|
void PolicyEngine::PPSTimerCallback() {
|
|
|
|
|
|
|
|
|
|
if (PPSTimerEnabled) {
|
|
|
|
|
if (PPSTimerEnabled && state == policy_engine_state::PESinkReady) {
|
|
|
|
|
// I believe even once per second is totally fine, but leaning on faster since everything seems cool with faster
|
|
|
|
|
// Have seen everything from 10ms to 1 second :D
|
|
|
|
|
if (xTaskGetTickCount() - PPSTimeLastEvent > 3 * TICKS_100MS) {
|
|
|
|
|
// Send a new PPS message
|
|
|
|
|
PPSTimeLastEvent = xTaskGetTickCount();
|
|
|
|
|
notify(Notifications::PDB_EVT_PE_PPS_REQUEST);
|
|
|
|
|
}
|
|
|
|
|
// if ((xTaskGetTickCount() - PPSTimeLastEvent) > (100)) {
|
|
|
|
|
// Send a new PPS message
|
|
|
|
|
PolicyEngine::notify(Notifications::PDB_EVT_PE_PPS_REQUEST);
|
|
|
|
|
PPSTimeLastEvent = xTaskGetTickCount();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|