Browse Source

Implement PD 3.0 collision avoidance

It's pretty easy to implement, it turns out!  A new event gets sent to
the protocol TX thread when the PE is starting an AMS.  Just before the
message is transmitted, the TX thread checks if that event was received,
and if it was, it waits for the Type-C Current to look like 3.0 A
(SinkTxOk) before proceeding.  Now, to the best of my knowledge, we're
actually doing Power Delivery 3.0 as correctly as we ever did Power
Delivery 2.0, which is to say, everything is right except we don't do
BIST.
Clara Hobbs 4 years ago
parent
commit
c62fe6a2a2

+ 14
- 3
lib/docs/firmware_structure.svg View File

@@ -363,9 +363,9 @@
363 363
      borderopacity="1.0"
364 364
      inkscape:pageopacity="0.0"
365 365
      inkscape:pageshadow="2"
366
-     inkscape:zoom="3.959798"
367
-     inkscape:cx="149.55024"
368
-     inkscape:cy="821.73649"
366
+     inkscape:zoom="5.6"
367
+     inkscape:cx="193.2269"
368
+     inkscape:cy="800.04611"
369 369
      inkscape:document-units="mm"
370 370
      inkscape:current-layer="layer1"
371 371
      showgrid="true"
@@ -957,5 +957,16 @@
957 957
          x="85.978149"
958 958
          id="tspan5148"
959 959
          sodipodi:role="line">PPS_REQUEST</tspan></text>
960
+    <text
961
+       id="text972"
962
+       y="91.465988"
963
+       x="82.486923"
964
+       style="font-style:normal;font-weight:normal;font-size:2.11666656px;line-height:3.30729151px;font-family:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.13229166px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
965
+       xml:space="preserve"><tspan
966
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:1.76388884px;font-family:'Source Code Pro';-inkscape-font-specification:'Source Code Pro';text-align:end;text-anchor:end;stroke-width:0.13229166px"
967
+         y="91.465988"
968
+         x="82.486923"
969
+         id="tspan970"
970
+         sodipodi:role="line">START_AMS</tspan></text>
960 971
   </g>
961 972
 </svg>

+ 3
- 1
lib/include/pdb_fusb.h View File

@@ -45,7 +45,9 @@ enum fusb_typec_current {
45 45
     fusb_tcc_none = 0,
46 46
     fusb_tcc_default = 1,
47 47
     fusb_tcc_1_5 = 2,
48
-    fusb_tcc_3_0 = 3
48
+    fusb_sink_tx_ng = 2,
49
+    fusb_tcc_3_0 = 3,
50
+    fusb_sink_tx_ok = 3
49 51
 };
50 52
 
51 53
 

+ 6
- 0
lib/src/policy_engine.c View File

@@ -350,6 +350,8 @@ static enum policy_engine_state pe_sink_ready(struct pdb_config *cfg)
350 350
 
351 351
     /* If the DPM wants us to, send a Get_Source_Cap message */
352 352
     if (evt & PDB_EVT_PE_GET_SOURCE_CAP) {
353
+        /* Tell the protocol layer we're starting an AMS */
354
+        chEvtSignal(cfg->prl.tx_thread, PDB_EVT_PRLTX_START_AMS);
353 355
         return PESinkGetSourceCap;
354 356
     }
355 357
 
@@ -363,11 +365,15 @@ static enum policy_engine_state pe_sink_ready(struct pdb_config *cfg)
363 365
             chPoolFree(&pdb_msg_pool, cfg->pe._message);
364 366
             cfg->pe._message = NULL;
365 367
         }
368
+        /* Tell the protocol layer we're starting an AMS */
369
+        chEvtSignal(cfg->prl.tx_thread, PDB_EVT_PRLTX_START_AMS);
366 370
         return PESinkEvalCap;
367 371
     }
368 372
 
369 373
     /* If SinkPPSPeriodicTimer ran out, send a new request */
370 374
     if (evt & PDB_EVT_PE_PPS_REQUEST) {
375
+        /* Tell the protocol layer we're starting an AMS */
376
+        chEvtSignal(cfg->prl.tx_thread, PDB_EVT_PRLTX_START_AMS);
371 377
         return PESinkSelectCap;
372 378
     }
373 379
 

+ 11
- 0
lib/src/protocol_tx.c View File

@@ -131,6 +131,17 @@ static enum protocol_tx_state protocol_tx_construct_message(struct pdb_config *c
131 131
     cfg->prl._tx_message->hdr &= ~PD_HDR_MESSAGEID;
132 132
     cfg->prl._tx_message->hdr |= (cfg->prl._tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
133 133
 
134
+    /* PD 3.0 collision avoidance */
135
+    if ((cfg->pe.hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
136
+        /* If we're starting an AMS, wait for permission to transmit */
137
+        evt = chEvtGetAndClearEvents(PDB_EVT_PRLTX_START_AMS);
138
+        if (evt & PDB_EVT_PRLTX_START_AMS) {
139
+            while (fusb_get_typec_current(&cfg->fusb) != fusb_sink_tx_ok) {
140
+                chThdSleepMilliseconds(1);
141
+            }
142
+        }
143
+    }
144
+
134 145
     /* Send the message to the PHY */
135 146
     fusb_send_message(&cfg->fusb, cfg->prl._tx_message);
136 147
 

+ 1
- 0
lib/src/protocol_tx.h View File

@@ -32,6 +32,7 @@
32 32
 #define PDB_EVT_PRLTX_I_RETRYFAIL EVENT_MASK(2)
33 33
 #define PDB_EVT_PRLTX_DISCARD EVENT_MASK(3)
34 34
 #define PDB_EVT_PRLTX_MSG_TX EVENT_MASK(4)
35
+#define PDB_EVT_PRLTX_START_AMS EVENT_MASK(5)
35 36
 
36 37
 
37 38
 /*

Loading…
Cancel
Save