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 6 years ago
parent
commit
c62fe6a2a2

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

363
      borderopacity="1.0"
363
      borderopacity="1.0"
364
      inkscape:pageopacity="0.0"
364
      inkscape:pageopacity="0.0"
365
      inkscape:pageshadow="2"
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
      inkscape:document-units="mm"
369
      inkscape:document-units="mm"
370
      inkscape:current-layer="layer1"
370
      inkscape:current-layer="layer1"
371
      showgrid="true"
371
      showgrid="true"
957
          x="85.978149"
957
          x="85.978149"
958
          id="tspan5148"
958
          id="tspan5148"
959
          sodipodi:role="line">PPS_REQUEST</tspan></text>
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
   </g>
971
   </g>
961
 </svg>
972
 </svg>

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

45
     fusb_tcc_none = 0,
45
     fusb_tcc_none = 0,
46
     fusb_tcc_default = 1,
46
     fusb_tcc_default = 1,
47
     fusb_tcc_1_5 = 2,
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
 
350
 
351
     /* If the DPM wants us to, send a Get_Source_Cap message */
351
     /* If the DPM wants us to, send a Get_Source_Cap message */
352
     if (evt & PDB_EVT_PE_GET_SOURCE_CAP) {
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
         return PESinkGetSourceCap;
355
         return PESinkGetSourceCap;
354
     }
356
     }
355
 
357
 
363
             chPoolFree(&pdb_msg_pool, cfg->pe._message);
365
             chPoolFree(&pdb_msg_pool, cfg->pe._message);
364
             cfg->pe._message = NULL;
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
         return PESinkEvalCap;
370
         return PESinkEvalCap;
367
     }
371
     }
368
 
372
 
369
     /* If SinkPPSPeriodicTimer ran out, send a new request */
373
     /* If SinkPPSPeriodicTimer ran out, send a new request */
370
     if (evt & PDB_EVT_PE_PPS_REQUEST) {
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
         return PESinkSelectCap;
377
         return PESinkSelectCap;
372
     }
378
     }
373
 
379
 

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

131
     cfg->prl._tx_message->hdr &= ~PD_HDR_MESSAGEID;
131
     cfg->prl._tx_message->hdr &= ~PD_HDR_MESSAGEID;
132
     cfg->prl._tx_message->hdr |= (cfg->prl._tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
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
     /* Send the message to the PHY */
145
     /* Send the message to the PHY */
135
     fusb_send_message(&cfg->fusb, cfg->prl._tx_message);
146
     fusb_send_message(&cfg->fusb, cfg->prl._tx_message);
136
 
147
 

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

32
 #define PDB_EVT_PRLTX_I_RETRYFAIL EVENT_MASK(2)
32
 #define PDB_EVT_PRLTX_I_RETRYFAIL EVENT_MASK(2)
33
 #define PDB_EVT_PRLTX_DISCARD EVENT_MASK(3)
33
 #define PDB_EVT_PRLTX_DISCARD EVENT_MASK(3)
34
 #define PDB_EVT_PRLTX_MSG_TX EVENT_MASK(4)
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