Browse Source

Add SinkPPSPeriodicTimer

Now if we make a request for a PPS APDO, the SinkPPSPeriodicTimer is
run, forcing a new request to be made every 10 s.  This is important
because without it, the Source Shall perform a Hard Reset 15 s after the
request is made.
Clara Hobbs 6 years ago
parent
commit
53afb2db42
4 changed files with 69 additions and 7 deletions
  1. 12
    3
      lib/include/pd.h
  2. 6
    2
      lib/include/pdb_pe.h
  3. 50
    2
      lib/src/policy_engine.c
  4. 1
    0
      lib/src/policy_engine.h

+ 12
- 3
lib/include/pd.h View File

142
 #define PD_PDO_TYPE (0x3 << PD_PDO_TYPE_SHIFT)
142
 #define PD_PDO_TYPE (0x3 << PD_PDO_TYPE_SHIFT)
143
 
143
 
144
 /* PDO types */
144
 /* PDO types */
145
-#define PD_PDO_TYPE_FIXED (0x0 << PD_PDO_TYPE_SHIFT)
146
-#define PD_PDO_TYPE_BATTERY (0x1 << PD_PDO_TYPE_SHIFT)
147
-#define PD_PDO_TYPE_VARIABLE (0x2 << PD_PDO_TYPE_SHIFT)
145
+#define PD_PDO_TYPE_FIXED ((unsigned) (0x0 << PD_PDO_TYPE_SHIFT))
146
+#define PD_PDO_TYPE_BATTERY ((unsigned) (0x1 << PD_PDO_TYPE_SHIFT))
147
+#define PD_PDO_TYPE_VARIABLE ((unsigned) (0x2 << PD_PDO_TYPE_SHIFT))
148
+#define PD_PDO_TYPE_AUGMENTED ((unsigned) (0x3 << PD_PDO_TYPE_SHIFT))
149
+
150
+#define PD_APDO_TYPE_SHIFT 28
151
+#define PD_APDO_TYPE (0x3 << PD_APDO_TYPE_SHIFT)
152
+
153
+/* APDO types */
154
+#define PD_APDO_TYPE_PPS (0x0 << PD_APDO_TYPE_SHIFT)
148
 
155
 
149
 /* PD Source Fixed PDO */
156
 /* PD Source Fixed PDO */
150
 #define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT 29
157
 #define PD_PDO_SRC_FIXED_DUAL_ROLE_PWR_SHIFT 29
214
 #define PD_RDO_UNCHUNKED_EXT_MSG (1 << PD_RDO_UNCHUNKED_EXT_MSG_SHIFT)
221
 #define PD_RDO_UNCHUNKED_EXT_MSG (1 << PD_RDO_UNCHUNKED_EXT_MSG_SHIFT)
215
 
222
 
216
 #define PD_RDO_OBJPOS_SET(i) (((i) << PD_RDO_OBJPOS_SHIFT) & PD_RDO_OBJPOS)
223
 #define PD_RDO_OBJPOS_SET(i) (((i) << PD_RDO_OBJPOS_SHIFT) & PD_RDO_OBJPOS)
224
+#define PD_RDO_OBJPOS_GET(msg) (((msg)->obj[0] & PD_RDO_OBJPOS) >> PD_RDO_OBJPOS_SHIFT)
217
 
225
 
218
 /* Fixed and Variable RDO, no GiveBack support */
226
 /* Fixed and Variable RDO, no GiveBack support */
219
 #define PD_RDO_FV_CURRENT_SHIFT 10
227
 #define PD_RDO_FV_CURRENT_SHIFT 10
245
 #define PD_T_SENDER_RESPONSE MS2ST(27)
253
 #define PD_T_SENDER_RESPONSE MS2ST(27)
246
 #define PD_T_SINK_REQUEST MS2ST(100)
254
 #define PD_T_SINK_REQUEST MS2ST(100)
247
 #define PD_T_TYPEC_SINK_WAIT_CAP MS2ST(465)
255
 #define PD_T_TYPEC_SINK_WAIT_CAP MS2ST(465)
256
+#define PD_T_PPS_REQUEST S2ST(10)
248
 /* This is actually from Type-C, not Power Delivery, but who cares? */
257
 /* This is actually from Type-C, not Power Delivery, but who cares? */
249
 #define PD_T_PD_DEBOUNCE MS2ST(15)
258
 #define PD_T_PD_DEBOUNCE MS2ST(15)
250
 
259
 

+ 6
- 2
lib/include/pdb_pe.h View File

30
  * Events for the Policy Engine thread, sent by user code
30
  * Events for the Policy Engine thread, sent by user code
31
  */
31
  */
32
 /* Tell the PE to send a Get_Source_Cap message */
32
 /* Tell the PE to send a Get_Source_Cap message */
33
-#define PDB_EVT_PE_GET_SOURCE_CAP EVENT_MASK(6)
33
+#define PDB_EVT_PE_GET_SOURCE_CAP EVENT_MASK(7)
34
 /* Tell the PE that new power is required */
34
 /* Tell the PE that new power is required */
35
-#define PDB_EVT_PE_NEW_POWER EVENT_MASK(7)
35
+#define PDB_EVT_PE_NEW_POWER EVENT_MASK(8)
36
 
36
 
37
 
37
 
38
 /*
38
 /*
60
     int8_t _hard_reset_counter;
60
     int8_t _hard_reset_counter;
61
     /* The result of the last Type-C Current match comparison */
61
     /* The result of the last Type-C Current match comparison */
62
     int8_t _old_tcc_match;
62
     int8_t _old_tcc_match;
63
+    /* The index of the first PPS APDO */
64
+    uint8_t _pps_index;
65
+    /* Virtual timer for SinkPPSPeriodicTimer */
66
+    virtual_timer_t _sink_pps_periodic_timer;
63
     /* Queue for the PE mailbox */
67
     /* Queue for the PE mailbox */
64
     msg_t _mailbox_queue[PDB_MSG_POOL_SIZE];
68
     msg_t _mailbox_queue[PDB_MSG_POOL_SIZE];
65
 };
69
 };

+ 50
- 2
lib/src/policy_engine.c View File

27
 #include "fusb302b.h"
27
 #include "fusb302b.h"
28
 
28
 
29
 
29
 
30
+static void pe_sink_pps_periodic_timer_cb(void *cfg)
31
+{
32
+    /* Signal the PE thread to make a new PPS request */
33
+    chSysLockFromISR();
34
+    chEvtSignalI(((struct pdb_config *) cfg)->pe.thread, PDB_EVT_PE_PPS_REQUEST);
35
+    chSysUnlockFromISR();
36
+}
37
+
38
+
30
 enum policy_engine_state {
39
 enum policy_engine_state {
31
     PESinkStartup,
40
     PESinkStartup,
32
     PESinkDiscovery,
41
     PESinkDiscovery,
133
 
142
 
134
 static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
143
 static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
135
 {
144
 {
145
+    /* If we have a message, remember the index of the first PPS APDO so we can
146
+     * check if the request is for a PPS APDO in PE_SNK_Select_Cap. */
147
+    if (cfg->pe._message != NULL) {
148
+        /* Start by assuming we won't find a PPS APDO (set the index greater
149
+         * than the maximum possible) */
150
+        cfg->pe._pps_index = 8;
151
+        /* Search for the first PPS APDO */
152
+        for (int8_t i = 0; i < PD_NUMOBJ_GET(cfg->pe._message); i++) {
153
+            if ((cfg->pe._message->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED
154
+                    && (cfg->pe._message->obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS) {
155
+                cfg->pe._pps_index = i + 1;
156
+                break;
157
+            }
158
+        }
159
+    }
136
     /* Get a message object for the request if we don't have one already */
160
     /* Get a message object for the request if we don't have one already */
137
     if (cfg->pe._last_dpm_request == NULL) {
161
     if (cfg->pe._last_dpm_request == NULL) {
138
         cfg->pe._last_dpm_request = chPoolAlloc(&pdb_msg_pool);
162
         cfg->pe._last_dpm_request = chPoolAlloc(&pdb_msg_pool);
165
         return PESinkHardReset;
189
         return PESinkHardReset;
166
     }
190
     }
167
 
191
 
192
+    /* If we're using PD 3.0 */
193
+    if ((cfg->pe.hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
194
+        /* If the request was for a PPS APDO, start SinkPPSPeriodicTimer */
195
+        if (PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request) >= cfg->pe._pps_index) {
196
+            chVTSet(&cfg->pe._sink_pps_periodic_timer, PD_T_PPS_REQUEST,
197
+                    pe_sink_pps_periodic_timer_cb, cfg);
198
+        /* Otherwise, stop SinkPPSPeriodicTimer */
199
+        } else {
200
+            chVTReset(&cfg->pe._sink_pps_periodic_timer);
201
+        }
202
+    }
203
+    /* This will use a virtual timer to send an event flag to this thread after
204
+     * PD_T_PPS_REQUEST */
205
+
168
     /* Wait for a response */
206
     /* Wait for a response */
169
     evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
207
     evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
170
             PD_T_SENDER_RESPONSE);
208
             PD_T_SENDER_RESPONSE);
278
     if (cfg->pe._min_power) {
316
     if (cfg->pe._min_power) {
279
         evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET
317
         evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET
280
                 | PDB_EVT_PE_I_OVRTEMP | PDB_EVT_PE_GET_SOURCE_CAP
318
                 | PDB_EVT_PE_I_OVRTEMP | PDB_EVT_PE_GET_SOURCE_CAP
281
-                | PDB_EVT_PE_NEW_POWER, PD_T_SINK_REQUEST);
319
+                | PDB_EVT_PE_NEW_POWER | PDB_EVT_PE_PPS_REQUEST,
320
+                PD_T_SINK_REQUEST);
282
     } else {
321
     } else {
283
         evt = chEvtWaitAny(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET
322
         evt = chEvtWaitAny(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET
284
                 | PDB_EVT_PE_I_OVRTEMP | PDB_EVT_PE_GET_SOURCE_CAP
323
                 | PDB_EVT_PE_I_OVRTEMP | PDB_EVT_PE_GET_SOURCE_CAP
285
-                | PDB_EVT_PE_NEW_POWER);
324
+                | PDB_EVT_PE_NEW_POWER | PDB_EVT_PE_PPS_REQUEST);
286
     }
325
     }
287
 
326
 
288
     /* If we got reset signaling, transition to default */
327
     /* If we got reset signaling, transition to default */
313
         return PESinkEvalCap;
352
         return PESinkEvalCap;
314
     }
353
     }
315
 
354
 
355
+    /* If SinkPPSPeriodicTimer ran out, send a new request */
356
+    if (evt & PDB_EVT_PE_PPS_REQUEST) {
357
+        return PESinkSelectCap;
358
+    }
359
+
316
     /* If no event was received, the timer ran out. */
360
     /* If no event was received, the timer ran out. */
317
     if (evt == 0) {
361
     if (evt == 0) {
318
         /* Repeat our Request message */
362
         /* Repeat our Request message */
720
 
764
 
721
     /* Initialize the mailbox */
765
     /* Initialize the mailbox */
722
     chMBObjectInit(&cfg->pe.mailbox, cfg->pe._mailbox_queue, PDB_MSG_POOL_SIZE);
766
     chMBObjectInit(&cfg->pe.mailbox, cfg->pe._mailbox_queue, PDB_MSG_POOL_SIZE);
767
+    /* Initialize the VT for SinkPPSPeriodicTimer */
768
+    chVTObjectInit(&cfg->pe._sink_pps_periodic_timer);
723
     /* Initialize the old_tcc_match */
769
     /* Initialize the old_tcc_match */
724
     cfg->pe._old_tcc_match = -1;
770
     cfg->pe._old_tcc_match = -1;
771
+    /* Initialize the pps_index */
772
+    cfg->pe._pps_index = 8;
725
     /* Initialize the PD message header template */
773
     /* Initialize the PD message header template */
726
     cfg->pe.hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK;
774
     cfg->pe.hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK;
727
 
775
 

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

35
 #define PDB_EVT_PE_TX_ERR EVENT_MASK(3)
35
 #define PDB_EVT_PE_TX_ERR EVENT_MASK(3)
36
 #define PDB_EVT_PE_HARD_SENT EVENT_MASK(4)
36
 #define PDB_EVT_PE_HARD_SENT EVENT_MASK(4)
37
 #define PDB_EVT_PE_I_OVRTEMP EVENT_MASK(5)
37
 #define PDB_EVT_PE_I_OVRTEMP EVENT_MASK(5)
38
+#define PDB_EVT_PE_PPS_REQUEST EVENT_MASK(6)
38
 
39
 
39
 
40
 
40
 /*
41
 /*

Loading…
Cancel
Save