From fc08dc42fa2f3c4dfe6221be10a743049dc62c31 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Mon, 5 Apr 2021 14:12:44 +1000 Subject: [PATCH] Auto notify tx --- source/Core/Drivers/FUSB302/pdb_conf.h | 10 +- source/Core/Drivers/FUSB302/policy_engine.cpp | 99 +++++++------------ source/Core/Drivers/FUSB302/policy_engine.h | 13 +-- source/Core/Drivers/FUSB302/protocol_rx.cpp | 2 +- source/Core/Drivers/FUSB302/protocol_tx.cpp | 4 +- 5 files changed, 54 insertions(+), 74 deletions(-) diff --git a/source/Core/Drivers/FUSB302/pdb_conf.h b/source/Core/Drivers/FUSB302/pdb_conf.h index fc1e4188..640ea233 100644 --- a/source/Core/Drivers/FUSB302/pdb_conf.h +++ b/source/Core/Drivers/FUSB302/pdb_conf.h @@ -19,13 +19,13 @@ #define PDB_CONF_H /* Number of messages in the message pool */ -#define PDB_MSG_POOL_SIZE 4 +#define PDB_MSG_POOL_SIZE 8 #define EVENT_MASK(x) (1 << x) -#define eventmask_t uint32_t + /* PD Buddy thread priorities */ -#define PDB_PRIO_PE (osPriorityNormal) -#define PDB_PRIO_PRL (osPriorityBelowNormal) -#define PDB_PRIO_PRL_INT_N (osPriorityLow) +#define PDB_PRIO_PE (osPriorityBelowNormal) +#define PDB_PRIO_PRL (osPriorityNormal) +#define PDB_PRIO_PRL_INT_N (osPriorityAboveNormal) #endif /* PDB_CONF_H */ diff --git a/source/Core/Drivers/FUSB302/policy_engine.cpp b/source/Core/Drivers/FUSB302/policy_engine.cpp index cc07544e..c22ff329 100644 --- a/source/Core/Drivers/FUSB302/policy_engine.cpp +++ b/source/Core/Drivers/FUSB302/policy_engine.cpp @@ -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(); + // } } } diff --git a/source/Core/Drivers/FUSB302/policy_engine.h b/source/Core/Drivers/FUSB302/policy_engine.h index a8a91d1e..1cbe034b 100644 --- a/source/Core/Drivers/FUSB302/policy_engine.h +++ b/source/Core/Drivers/FUSB302/policy_engine.h @@ -62,11 +62,12 @@ public: PDB_EVT_PE_MSG_RX_PEND = EVENT_MASK(7), /* Never send this from user area*/ PDB_EVT_PE_GET_SOURCE_CAP = EVENT_MASK(8), PDB_EVT_PE_NEW_POWER = EVENT_MASK(9), - PDB_EVT_PE_ALL = (PDB_EVT_PE_NEW_POWER - 1), - + PDB_EVT_PE_ALL = (EVENT_MASK(10) - 1), }; // Send a notification static void notify(Notifications notification); + // Debugging allows looking at state + static uint32_t getState() { return (uint32_t)state; } private: static bool pdNegotiationComplete; @@ -92,9 +93,9 @@ private: PESinkDiscovery, PESinkWaitCap, PESinkEvalCap, - PESinkSelectCap, - PESinkTransitionSink, - PESinkReady, + PESinkSelectCap, // 4 + PESinkTransitionSink, // 5 + PESinkReady, // 6 PESinkGetSourceCap, PESinkGiveSinkCap, PESinkHardReset, @@ -125,7 +126,7 @@ private: static enum policy_engine_state pe_sink_source_unresponsive(); static EventGroupHandle_t xEventGroupHandle; static StaticEventGroup_t xCreatedEventGroup; - static uint32_t waitForEvent(uint32_t mask, TickType_t ticksToWait = portMAX_DELAY); + static EventBits_t waitForEvent(uint32_t mask, TickType_t ticksToWait = portMAX_DELAY); // Task resources static osThreadId TaskHandle; static const size_t TaskStackSize = 2048 / 4; diff --git a/source/Core/Drivers/FUSB302/protocol_rx.cpp b/source/Core/Drivers/FUSB302/protocol_rx.cpp index 73b9f095..b8556f31 100644 --- a/source/Core/Drivers/FUSB302/protocol_rx.cpp +++ b/source/Core/Drivers/FUSB302/protocol_rx.cpp @@ -34,7 +34,7 @@ union pd_msg ProtocolReceive::tempMessage; */ ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() { /* Wait for an event */ - eventmask_t evt = waitForEvent(PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND); + EventBits_t evt = waitForEvent(PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND); /* If we got a reset event, reset */ if (evt & PDB_EVT_PRLRX_RESET) { diff --git a/source/Core/Drivers/FUSB302/protocol_tx.cpp b/source/Core/Drivers/FUSB302/protocol_tx.cpp index e9563f59..7eaddfc7 100644 --- a/source/Core/Drivers/FUSB302/protocol_tx.cpp +++ b/source/Core/Drivers/FUSB302/protocol_tx.cpp @@ -252,7 +252,9 @@ void ProtocolTransmit::init() { void ProtocolTransmit::pushMessage(union pd_msg *msg) { if (messagesWaiting) { - xQueueSend(messagesWaiting, msg, 100); + if (xQueueSend(messagesWaiting, msg, 100) == pdTRUE) { + notify(ProtocolTransmit::Notifications::PDB_EVT_PRLTX_MSG_TX); + } } }