Browse Source

Make the library work, to an extent

The code compiles again, and it seems to work as it did before.  There's
still a lot to do (we still have a mess of globals), but the PE
correctly calls the new DPM functions via the list of callbacks in the
configuration object.
Clara Hobbs 6 years ago
parent
commit
74e4a5e160

+ 1
- 1
Makefile View File

195
 #
195
 #
196
 
196
 
197
 # List all user C define here, like -D_DEBUG=1
197
 # List all user C define here, like -D_DEBUG=1
198
-UDEFS = -DPDB_CONFIG_BASE=0x0800F800
198
+UDEFS = -DPDBS_CONFIG_BASE=0x0800F800
199
 
199
 
200
 # Define ASM defines here
200
 # Define ASM defines here
201
 UADEFS =
201
 UADEFS =

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

21
 
21
 
22
 #include <stdint.h>
22
 #include <stdint.h>
23
 
23
 
24
+#include <pdb_fusb.h>
25
+
24
 #include "messages.h"
26
 #include "messages.h"
25
 
27
 
26
 
28
 
306
 /*
308
 /*
307
  * Initialization routine for the FUSB302B
309
  * Initialization routine for the FUSB302B
308
  */
310
  */
309
-void fusb_setup(void);
311
+void fusb_setup(struct pdb_fusb_config *);
310
 
312
 
311
 /*
313
 /*
312
  * Reset the FUSB302B
314
  * Reset the FUSB302B

+ 1
- 1
lib/include/pdb.h View File

34
  */
34
  */
35
 struct pdb_config {
35
 struct pdb_config {
36
     /* Configuration information for the FUSB302B* chip */
36
     /* Configuration information for the FUSB302B* chip */
37
-    struct pdb_fusb_config fusb_config;
37
+    struct pdb_fusb_config fusb;
38
     /* DPM callbacks */
38
     /* DPM callbacks */
39
     struct pdb_dpm_callbacks dpm;
39
     struct pdb_dpm_callbacks dpm;
40
     /* Pointer to port-specific DPM data */
40
     /* Pointer to port-specific DPM data */

+ 3
- 2
lib/include/pdb_dpm.h View File

34
 typedef bool (*pdb_dpm_eval_cap_func)(struct pdb_config *,
34
 typedef bool (*pdb_dpm_eval_cap_func)(struct pdb_config *,
35
         const union pd_msg *, union pd_msg *);
35
         const union pd_msg *, union pd_msg *);
36
 typedef void (*pdb_dpm_get_sink_cap_func)(struct pdb_config *, union pd_msg *);
36
 typedef void (*pdb_dpm_get_sink_cap_func)(struct pdb_config *, union pd_msg *);
37
-typedef void (*pdb_dpm_tcc_func)(struct pdb_config *, enum fusb_typec_current);
37
+typedef bool (*pdb_dpm_giveback_func)(struct pdb_config *);
38
+typedef bool (*pdb_dpm_tcc_func)(struct pdb_config *, enum fusb_typec_current);
38
 
39
 
39
 /*
40
 /*
40
  * PD Buddy firmware library device policy manager callback structure
41
  * PD Buddy firmware library device policy manager callback structure
45
 struct pdb_dpm_callbacks {
46
 struct pdb_dpm_callbacks {
46
     pdb_dpm_eval_cap_func evaluate_capability;
47
     pdb_dpm_eval_cap_func evaluate_capability;
47
     pdb_dpm_get_sink_cap_func get_sink_capability;
48
     pdb_dpm_get_sink_cap_func get_sink_capability;
48
-    pdb_dpm_func giveback_enabled;
49
+    pdb_dpm_giveback_func giveback_enabled;
49
     pdb_dpm_tcc_func evaluate_typec_current; /* Optional */
50
     pdb_dpm_tcc_func evaluate_typec_current; /* Optional */
50
     pdb_dpm_func pd_start; /* Optional */
51
     pdb_dpm_func pd_start; /* Optional */
51
     /* dpm_sink_standby is called in PE_SNK_Select_Capability to ensure power
52
     /* dpm_sink_standby is called in PE_SNK_Select_Capability to ensure power

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

21
 
21
 
22
 #include <ch.h>
22
 #include <ch.h>
23
 
23
 
24
+#include <pdb.h>
25
+
24
 
26
 
25
 /* Events for the Policy Engine thread */
27
 /* Events for the Policy Engine thread */
26
 #define PDB_EVT_PE_RESET EVENT_MASK(0)
28
 #define PDB_EVT_PE_RESET EVENT_MASK(0)
41
 /*
43
 /*
42
  * Start the Policy Engine thread
44
  * Start the Policy Engine thread
43
  */
45
  */
44
-void pdb_pe_run(void);
46
+void pdb_pe_run(struct pdb_config *cfg);
45
 
47
 
46
 
48
 
47
 #endif /* PDB_POLICY_ENGINE_H */
49
 #endif /* PDB_POLICY_ENGINE_H */

+ 3
- 3
lib/src/fusb302b.c View File

142
     i2cReleaseBus(&I2CD2);
142
     i2cReleaseBus(&I2CD2);
143
 }
143
 }
144
 
144
 
145
-void fusb_setup(void)
145
+void fusb_setup(struct pdb_fusb_config *cfg)
146
 {
146
 {
147
-    i2cAcquireBus(&I2CD2);
147
+    i2cAcquireBus(cfg->i2cp);
148
 
148
 
149
     /* Fully reset the FUSB302B */
149
     /* Fully reset the FUSB302B */
150
     fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES);
150
     fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES);
186
     /* Reset the PD logic */
186
     /* Reset the PD logic */
187
     fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
187
     fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
188
 
188
 
189
-    i2cReleaseBus(&I2CD2);
189
+    i2cReleaseBus(cfg->i2cp);
190
 }
190
 }
191
 
191
 
192
 void fusb_get_status(union fusb_status *status)
192
 void fusb_get_status(union fusb_status *status)

+ 3
- 3
lib/src/int_n.h View File

16
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
  */
17
  */
18
 
18
 
19
-#ifndef PDB_INT_N_H
20
-#define PDB_INT_N_H
19
+#ifndef PDB_INT_N_OLD_H
20
+#define PDB_INT_N_OLD_H
21
 
21
 
22
 
22
 
23
 /*
23
 /*
26
 void pdb_int_n_run(void);
26
 void pdb_int_n_run(void);
27
 
27
 
28
 
28
 
29
-#endif /* PDB_INT_N_H */
29
+#endif /* PDB_INT_N_OLD_H */

+ 5
- 5
lib/src/pdb.c View File

28
 void pdb_init(struct pdb_config *cfg)
28
 void pdb_init(struct pdb_config *cfg)
29
 {
29
 {
30
     /* Initialize the FUSB302B */
30
     /* Initialize the FUSB302B */
31
-    fusb_setup(cfg);
31
+    fusb_setup(&cfg->fusb);
32
 
32
 
33
     /* Create the policy engine thread. */
33
     /* Create the policy engine thread. */
34
     pdb_pe_run(cfg);
34
     pdb_pe_run(cfg);
35
 
35
 
36
     /* Create the protocol layer threads. */
36
     /* Create the protocol layer threads. */
37
-    pdb_prlrx_run(cfg);
38
-    pdb_prltx_run(cfg);
39
-    pdb_hardrst_run(cfg);
37
+    pdb_prlrx_run(/*cfg*/);
38
+    pdb_prltx_run(/*cfg*/);
39
+    pdb_hardrst_run(/*cfg*/);
40
 
40
 
41
     /* Create the INT_N thread. */
41
     /* Create the INT_N thread. */
42
-    pdb_int_n_run(cfg);
42
+    pdb_int_n_run(/*cfg*/);
43
 }
43
 }

+ 45
- 47
lib/src/policy_engine.c View File

22
 
22
 
23
 #include "messages.h"
23
 #include "messages.h"
24
 #include "priorities.h"
24
 #include "priorities.h"
25
-#include "device_policy_manager.h"
26
 #include "protocol_tx.h"
25
 #include "protocol_tx.h"
27
 #include "hard_reset.h"
26
 #include "hard_reset.h"
28
 #include "fusb302b.h"
27
 #include "fusb302b.h"
65
 static msg_t pdb_pe_mailbox_queue[PDB_MSG_POOL_SIZE];
64
 static msg_t pdb_pe_mailbox_queue[PDB_MSG_POOL_SIZE];
66
 mailbox_t pdb_pe_mailbox;
65
 mailbox_t pdb_pe_mailbox;
67
 
66
 
68
-static enum policy_engine_state pe_sink_startup(void)
67
+static enum policy_engine_state pe_sink_startup(struct pdb_config *cfg)
69
 {
68
 {
70
     /* We don't have an explicit contract currently */
69
     /* We don't have an explicit contract currently */
71
     explicit_contract = false;
70
     explicit_contract = false;
72
     /* Tell the DPM that we've started negotiations */
71
     /* Tell the DPM that we've started negotiations */
73
-    pdb_dpm_pd_start();
72
+    cfg->dpm.pd_start(cfg);
74
 
73
 
75
     /* No need to reset the protocol layer here.  There are two ways into this
74
     /* No need to reset the protocol layer here.  There are two ways into this
76
      * state: startup and exiting hard reset.  On startup, the protocol layer
75
      * state: startup and exiting hard reset.  On startup, the protocol layer
81
     return PESinkDiscovery;
80
     return PESinkDiscovery;
82
 }
81
 }
83
 
82
 
84
-static enum policy_engine_state pe_sink_discovery(void)
83
+static enum policy_engine_state pe_sink_discovery(struct pdb_config *cfg)
85
 {
84
 {
86
     /* Wait for VBUS.  Since it's our only power source, we already know that
85
     /* Wait for VBUS.  Since it's our only power source, we already know that
87
      * we have it, so just move on. */
86
      * we have it, so just move on. */
89
     return PESinkWaitCap;
88
     return PESinkWaitCap;
90
 }
89
 }
91
 
90
 
92
-static enum policy_engine_state pe_sink_wait_cap(void)
91
+static enum policy_engine_state pe_sink_wait_cap(struct pdb_config *cfg)
93
 {
92
 {
94
     /* Fetch a message from the protocol layer */
93
     /* Fetch a message from the protocol layer */
95
     eventmask_t evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX
94
     eventmask_t evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX
134
     return PESinkHardReset;
133
     return PESinkHardReset;
135
 }
134
 }
136
 
135
 
137
-static enum policy_engine_state pe_sink_eval_cap(void)
136
+static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
138
 {
137
 {
139
     /* Get a message object for the request if we don't have one already */
138
     /* Get a message object for the request if we don't have one already */
140
     if (last_dpm_request == NULL) {
139
     if (last_dpm_request == NULL) {
141
         last_dpm_request = chPoolAlloc(&pdb_msg_pool);
140
         last_dpm_request = chPoolAlloc(&pdb_msg_pool);
142
     }
141
     }
143
     /* Ask the DPM what to request */
142
     /* Ask the DPM what to request */
144
-    capability_match = pdb_dpm_evaluate_capability(policy_engine_message,
143
+    capability_match = cfg->dpm.evaluate_capability(cfg, policy_engine_message,
145
             last_dpm_request);
144
             last_dpm_request);
146
     /* It's up to the DPM to free the Source_Capabilities message, which it can
145
     /* It's up to the DPM to free the Source_Capabilities message, which it can
147
      * do whenever it sees fit.  Just remove our reference to it since we won't
146
      * do whenever it sees fit.  Just remove our reference to it since we won't
151
     return PESinkSelectCap;
150
     return PESinkSelectCap;
152
 }
151
 }
153
 
152
 
154
-static enum policy_engine_state pe_sink_select_cap(void)
153
+static enum policy_engine_state pe_sink_select_cap(struct pdb_config *cfg)
155
 {
154
 {
156
     /* Transmit the request */
155
     /* Transmit the request */
157
     chMBPost(&pdb_prltx_mailbox, (msg_t) last_dpm_request, TIME_IMMEDIATE);
156
     chMBPost(&pdb_prltx_mailbox, (msg_t) last_dpm_request, TIME_IMMEDIATE);
186
         if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_ACCEPT
185
         if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_ACCEPT
187
                 && PD_NUMOBJ_GET(policy_engine_message) == 0) {
186
                 && PD_NUMOBJ_GET(policy_engine_message) == 0) {
188
             /* Transition to Sink Standby if necessary */
187
             /* Transition to Sink Standby if necessary */
189
-            pdb_dpm_sink_standby();
188
+            cfg->dpm.transition_standby(cfg);
190
 
189
 
191
             min_power = false;
190
             min_power = false;
192
 
191
 
227
     return PESinkHardReset;
226
     return PESinkHardReset;
228
 }
227
 }
229
 
228
 
230
-static enum policy_engine_state pe_sink_transition_sink(void)
229
+static enum policy_engine_state pe_sink_transition_sink(struct pdb_config *cfg)
231
 {
230
 {
232
     /* Wait for the PS_RDY message */
231
     /* Wait for the PS_RDY message */
233
     eventmask_t evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
232
     eventmask_t evt = chEvtWaitAnyTimeout(PDB_EVT_PE_MSG_RX | PDB_EVT_PE_RESET,
251
 
250
 
252
             /* Set the output appropriately */
251
             /* Set the output appropriately */
253
             if (!min_power) {
252
             if (!min_power) {
254
-                pdb_dpm_output_set(capability_match);
253
+                cfg->dpm.transition_requested(cfg);
255
             }
254
             }
256
 
255
 
257
             chPoolFree(&pdb_msg_pool, policy_engine_message);
256
             chPoolFree(&pdb_msg_pool, policy_engine_message);
262
             /* Turn off the power output before this hard reset to make sure we
261
             /* Turn off the power output before this hard reset to make sure we
263
              * don't supply an incorrect voltage to the device we're powering.
262
              * don't supply an incorrect voltage to the device we're powering.
264
              */
263
              */
265
-            pdb_dpm_output_set(false);
264
+            cfg->dpm.transition_default(cfg);
266
 
265
 
267
             chPoolFree(&pdb_msg_pool, policy_engine_message);
266
             chPoolFree(&pdb_msg_pool, policy_engine_message);
268
             policy_engine_message = NULL;
267
             policy_engine_message = NULL;
273
     return PESinkHardReset;
272
     return PESinkHardReset;
274
 }
273
 }
275
 
274
 
276
-static enum policy_engine_state pe_sink_ready(void)
275
+static enum policy_engine_state pe_sink_ready(struct pdb_config *cfg)
277
 {
276
 {
278
     eventmask_t evt;
277
     eventmask_t evt;
279
 
278
 
376
             /* Handle GotoMin messages */
375
             /* Handle GotoMin messages */
377
             } else if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_GOTOMIN
376
             } else if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_GOTOMIN
378
                     && PD_NUMOBJ_GET(policy_engine_message) == 0) {
377
                     && PD_NUMOBJ_GET(policy_engine_message) == 0) {
379
-                if (pdb_dpm_giveback_enabled()) {
380
-                    /* We support GiveBack, so go to minimum power */
381
-                    pdb_dpm_output_set(false);
378
+                if (cfg->dpm.giveback_enabled(cfg)) {
379
+                    /* Transition to the minimum current level */
380
+                    cfg->dpm.transition_min(cfg);
382
                     min_power = true;
381
                     min_power = true;
383
 
382
 
384
                     chPoolFree(&pdb_msg_pool, policy_engine_message);
383
                     chPoolFree(&pdb_msg_pool, policy_engine_message);
420
     return PESinkReady;
419
     return PESinkReady;
421
 }
420
 }
422
 
421
 
423
-static enum policy_engine_state pe_sink_get_source_cap(void)
422
+static enum policy_engine_state pe_sink_get_source_cap(struct pdb_config *cfg)
424
 {
423
 {
425
     /* Get a message object */
424
     /* Get a message object */
426
     union pd_msg *get_source_cap = chPoolAlloc(&pdb_msg_pool);
425
     union pd_msg *get_source_cap = chPoolAlloc(&pdb_msg_pool);
447
     return PESinkReady;
446
     return PESinkReady;
448
 }
447
 }
449
 
448
 
450
-static enum policy_engine_state pe_sink_give_sink_cap(void)
449
+static enum policy_engine_state pe_sink_give_sink_cap(struct pdb_config *cfg)
451
 {
450
 {
452
     /* Get a message object */
451
     /* Get a message object */
453
     union pd_msg *snk_cap = chPoolAlloc(&pdb_msg_pool);
452
     union pd_msg *snk_cap = chPoolAlloc(&pdb_msg_pool);
454
     /* Get our capabilities from the DPM */
453
     /* Get our capabilities from the DPM */
455
-    pdb_dpm_get_sink_capability(snk_cap);
454
+    cfg->dpm.get_sink_capability(cfg, snk_cap);
456
 
455
 
457
     /* Transmit our capabilities */
456
     /* Transmit our capabilities */
458
     chMBPost(&pdb_prltx_mailbox, (msg_t) snk_cap, TIME_IMMEDIATE);
457
     chMBPost(&pdb_prltx_mailbox, (msg_t) snk_cap, TIME_IMMEDIATE);
476
     return PESinkReady;
475
     return PESinkReady;
477
 }
476
 }
478
 
477
 
479
-static enum policy_engine_state pe_sink_hard_reset(void)
478
+static enum policy_engine_state pe_sink_hard_reset(struct pdb_config *cfg)
480
 {
479
 {
481
     /* If we've already sent the maximum number of hard resets, assume the
480
     /* If we've already sent the maximum number of hard resets, assume the
482
      * source is unresponsive. */
481
      * source is unresponsive. */
494
     return PESinkTransitionDefault;
493
     return PESinkTransitionDefault;
495
 }
494
 }
496
 
495
 
497
-static enum policy_engine_state pe_sink_transition_default(void)
496
+static enum policy_engine_state pe_sink_transition_default(struct pdb_config *cfg)
498
 {
497
 {
499
     explicit_contract = false;
498
     explicit_contract = false;
500
 
499
 
501
     /* Tell the DPM to transition to default power */
500
     /* Tell the DPM to transition to default power */
502
-    pdb_dpm_output_default();
501
+    cfg->dpm.transition_default(cfg);
503
 
502
 
504
     /* There is no local hardware to reset. */
503
     /* There is no local hardware to reset. */
505
     /* Since we never change our data role from UFP, there is no reason to set
504
     /* Since we never change our data role from UFP, there is no reason to set
511
     return PESinkStartup;
510
     return PESinkStartup;
512
 }
511
 }
513
 
512
 
514
-static enum policy_engine_state pe_sink_soft_reset(void)
513
+static enum policy_engine_state pe_sink_soft_reset(struct pdb_config *cfg)
515
 {
514
 {
516
     /* No need to explicitly reset the protocol layer here.  It resets itself
515
     /* No need to explicitly reset the protocol layer here.  It resets itself
517
      * when a Soft_Reset message is received. */
516
      * when a Soft_Reset message is received. */
541
     return PESinkWaitCap;
540
     return PESinkWaitCap;
542
 }
541
 }
543
 
542
 
544
-static enum policy_engine_state pe_sink_send_soft_reset(void)
543
+static enum policy_engine_state pe_sink_send_soft_reset(struct pdb_config *cfg)
545
 {
544
 {
546
     /* No need to explicitly reset the protocol layer here.  It resets itself
545
     /* No need to explicitly reset the protocol layer here.  It resets itself
547
      * just before a Soft_Reset message is transmitted. */
546
      * just before a Soft_Reset message is transmitted. */
604
     return PESinkHardReset;
603
     return PESinkHardReset;
605
 }
604
 }
606
 
605
 
607
-static enum policy_engine_state pe_sink_send_reject(void)
606
+static enum policy_engine_state pe_sink_send_reject(struct pdb_config *cfg)
608
 {
607
 {
609
     /* Get a message object */
608
     /* Get a message object */
610
     union pd_msg *reject = chPoolAlloc(&pdb_msg_pool);
609
     union pd_msg *reject = chPoolAlloc(&pdb_msg_pool);
637
 /*
636
 /*
638
  * When Power Delivery is unresponsive, fall back to Type-C Current
637
  * When Power Delivery is unresponsive, fall back to Type-C Current
639
  */
638
  */
640
-static enum policy_engine_state pe_sink_source_unresponsive(void)
639
+static enum policy_engine_state pe_sink_source_unresponsive(struct pdb_config *cfg)
641
 {
640
 {
642
     static int old_tcc_match = -1;
641
     static int old_tcc_match = -1;
643
-    int tcc_match = pdb_dpm_evaluate_typec_current(fusb_get_typec_current());
642
+    int tcc_match = cfg->dpm.evaluate_typec_current(cfg, fusb_get_typec_current());
644
 
643
 
645
     /* If the last two readings are the same, set the output */
644
     /* If the last two readings are the same, set the output */
646
     if (old_tcc_match == tcc_match) {
645
     if (old_tcc_match == tcc_match) {
647
-        pdb_dpm_output_set(tcc_match);
646
+        cfg->dpm.transition_typec(cfg);
648
     }
647
     }
649
 
648
 
650
     /* Remember whether or not the last measurement succeeded */
649
     /* Remember whether or not the last measurement succeeded */
660
  * Policy Engine state machine thread
659
  * Policy Engine state machine thread
661
  */
660
  */
662
 static THD_WORKING_AREA(waPolicyEngine, 128);
661
 static THD_WORKING_AREA(waPolicyEngine, 128);
663
-static THD_FUNCTION(PolicyEngine, arg) {
664
-    (void) arg;
662
+static THD_FUNCTION(PolicyEngine, cfg) {
665
     enum policy_engine_state state = PESinkStartup;
663
     enum policy_engine_state state = PESinkStartup;
666
 
664
 
667
     /* Initialize the mailbox */
665
     /* Initialize the mailbox */
670
     while (true) {
668
     while (true) {
671
         switch (state) {
669
         switch (state) {
672
             case PESinkStartup:
670
             case PESinkStartup:
673
-                state = pe_sink_startup();
671
+                state = pe_sink_startup(cfg);
674
                 break;
672
                 break;
675
             case PESinkDiscovery:
673
             case PESinkDiscovery:
676
-                state = pe_sink_discovery();
674
+                state = pe_sink_discovery(cfg);
677
                 break;
675
                 break;
678
             case PESinkWaitCap:
676
             case PESinkWaitCap:
679
-                state = pe_sink_wait_cap();
677
+                state = pe_sink_wait_cap(cfg);
680
                 break;
678
                 break;
681
             case PESinkEvalCap:
679
             case PESinkEvalCap:
682
-                state = pe_sink_eval_cap();
680
+                state = pe_sink_eval_cap(cfg);
683
                 break;
681
                 break;
684
             case PESinkSelectCap:
682
             case PESinkSelectCap:
685
-                state = pe_sink_select_cap();
683
+                state = pe_sink_select_cap(cfg);
686
                 break;
684
                 break;
687
             case PESinkTransitionSink:
685
             case PESinkTransitionSink:
688
-                state = pe_sink_transition_sink();
686
+                state = pe_sink_transition_sink(cfg);
689
                 break;
687
                 break;
690
             case PESinkReady:
688
             case PESinkReady:
691
-                state = pe_sink_ready();
689
+                state = pe_sink_ready(cfg);
692
                 break;
690
                 break;
693
             case PESinkGetSourceCap:
691
             case PESinkGetSourceCap:
694
-                state = pe_sink_get_source_cap();
692
+                state = pe_sink_get_source_cap(cfg);
695
                 break;
693
                 break;
696
             case PESinkGiveSinkCap:
694
             case PESinkGiveSinkCap:
697
-                state = pe_sink_give_sink_cap();
695
+                state = pe_sink_give_sink_cap(cfg);
698
                 break;
696
                 break;
699
             case PESinkHardReset:
697
             case PESinkHardReset:
700
-                state = pe_sink_hard_reset();
698
+                state = pe_sink_hard_reset(cfg);
701
                 break;
699
                 break;
702
             case PESinkTransitionDefault:
700
             case PESinkTransitionDefault:
703
-                state = pe_sink_transition_default();
701
+                state = pe_sink_transition_default(cfg);
704
                 break;
702
                 break;
705
             case PESinkSoftReset:
703
             case PESinkSoftReset:
706
-                state = pe_sink_soft_reset();
704
+                state = pe_sink_soft_reset(cfg);
707
                 break;
705
                 break;
708
             case PESinkSendSoftReset:
706
             case PESinkSendSoftReset:
709
-                state = pe_sink_send_soft_reset();
707
+                state = pe_sink_send_soft_reset(cfg);
710
                 break;
708
                 break;
711
             case PESinkSendReject:
709
             case PESinkSendReject:
712
-                state = pe_sink_send_reject();
710
+                state = pe_sink_send_reject(cfg);
713
                 break;
711
                 break;
714
             case PESinkSourceUnresponsive:
712
             case PESinkSourceUnresponsive:
715
-                state = pe_sink_source_unresponsive();
713
+                state = pe_sink_source_unresponsive(cfg);
716
                 break;
714
                 break;
717
             default:
715
             default:
718
                 /* This is an error.  It really shouldn't happen.  We might
716
                 /* This is an error.  It really shouldn't happen.  We might
723
     }
721
     }
724
 }
722
 }
725
 
723
 
726
-void pdb_pe_run(void)
724
+void pdb_pe_run(struct pdb_config *cfg)
727
 {
725
 {
728
     pdb_pe_thread = chThdCreateStatic(waPolicyEngine, sizeof(waPolicyEngine),
726
     pdb_pe_thread = chThdCreateStatic(waPolicyEngine, sizeof(waPolicyEngine),
729
-            PDB_PRIO_PE, PolicyEngine, NULL);
727
+            PDB_PRIO_PE, PolicyEngine, cfg);
730
 }
728
 }

+ 25
- 25
src/config.c View File

23
 #include "pd.h"
23
 #include "pd.h"
24
 
24
 
25
 
25
 
26
-/* Initialize the location of the configuration array.  PDB_CONFIG_BASE is set
26
+/* Initialize the location of the configuration array.  PDBS_CONFIG_BASE is set
27
  * in the Makefile. */
27
  * in the Makefile. */
28
-struct pdb_config *pdb_config_array = (struct pdb_config *) PDB_CONFIG_BASE;
28
+struct pdbs_config *pdbs_config_array = (struct pdbs_config *) PDBS_CONFIG_BASE;
29
 
29
 
30
 /* The location of the current configuration object.  NULL if not known or
30
 /* The location of the current configuration object.  NULL if not known or
31
  * there is no current configuration. */
31
  * there is no current configuration. */
32
-struct pdb_config *config_cur = NULL;
32
+struct pdbs_config *config_cur = NULL;
33
 
33
 
34
 
34
 
35
-void pdb_config_print(BaseSequentialStream *chp, const struct pdb_config *cfg)
35
+void pdbs_config_print(BaseSequentialStream *chp, const struct pdbs_config *cfg)
36
 {
36
 {
37
     /* Print the status */
37
     /* Print the status */
38
     chprintf(chp, "status: ");
38
     chprintf(chp, "status: ");
39
     switch (cfg->status) {
39
     switch (cfg->status) {
40
-        case PDB_CONFIG_STATUS_INVALID:
40
+        case PDBS_CONFIG_STATUS_INVALID:
41
             chprintf(chp, "in");
41
             chprintf(chp, "in");
42
             /* fall-through */
42
             /* fall-through */
43
-        case PDB_CONFIG_STATUS_VALID:
43
+        case PDBS_CONFIG_STATUS_VALID:
44
             chprintf(chp, "valid\r\n");
44
             chprintf(chp, "valid\r\n");
45
             break;
45
             break;
46
-        case PDB_CONFIG_STATUS_EMPTY:
46
+        case PDBS_CONFIG_STATUS_EMPTY:
47
             chprintf(chp, "empty\r\n");
47
             chprintf(chp, "empty\r\n");
48
             /* Stop early because the rest of the information is meaningless in
48
             /* Stop early because the rest of the information is meaningless in
49
              * this case. */
49
              * this case. */
58
     if (cfg->flags == 0) {
58
     if (cfg->flags == 0) {
59
         chprintf(chp, "(none)");
59
         chprintf(chp, "(none)");
60
     }
60
     }
61
-    if (cfg->flags & PDB_CONFIG_FLAGS_GIVEBACK) {
61
+    if (cfg->flags & PDBS_CONFIG_FLAGS_GIVEBACK) {
62
         chprintf(chp, "GiveBack ");
62
         chprintf(chp, "GiveBack ");
63
     }
63
     }
64
-    if (cfg->flags & PDB_CONFIG_FLAGS_VAR_BAT) {
64
+    if (cfg->flags & PDBS_CONFIG_FLAGS_VAR_BAT) {
65
         chprintf(chp, "Var/Bat ");
65
         chprintf(chp, "Var/Bat ");
66
     }
66
     }
67
     chprintf(chp, "\r\n");
67
     chprintf(chp, "\r\n");
69
     /* Print voltages and current */
69
     /* Print voltages and current */
70
     chprintf(chp, "v: %d.%02d V\r\n", PD_PDV_V(cfg->v), PD_PDV_CV(cfg->v));
70
     chprintf(chp, "v: %d.%02d V\r\n", PD_PDV_V(cfg->v), PD_PDV_CV(cfg->v));
71
     chprintf(chp, "i: %d.%02d A\r\n", PD_PDI_A(cfg->i), PD_PDI_CA(cfg->i));
71
     chprintf(chp, "i: %d.%02d A\r\n", PD_PDI_A(cfg->i), PD_PDI_CA(cfg->i));
72
-    if (cfg->flags & PDB_CONFIG_FLAGS_VAR_BAT) {
72
+    if (cfg->flags & PDBS_CONFIG_FLAGS_VAR_BAT) {
73
         chprintf(chp, "v_min: %d.%02d V\r\n", PD_PDV_V(cfg->v_min),
73
         chprintf(chp, "v_min: %d.%02d V\r\n", PD_PDV_V(cfg->v_min),
74
                  PD_PDV_CV(cfg->v_min));
74
                  PD_PDV_CV(cfg->v_min));
75
         chprintf(chp, "v_max: %d.%02d V\r\n", PD_PDV_V(cfg->v_max),
75
         chprintf(chp, "v_max: %d.%02d V\r\n", PD_PDV_V(cfg->v_max),
144
     /* Set the PER bit in the FLASH_CR register to enable page erasing */
144
     /* Set the PER bit in the FLASH_CR register to enable page erasing */
145
     FLASH->CR |= FLASH_CR_PER;
145
     FLASH->CR |= FLASH_CR_PER;
146
     /* Program the FLASH_AR register to select a page to erase */
146
     /* Program the FLASH_AR register to select a page to erase */
147
-    FLASH->AR = (int) pdb_config_array;
147
+    FLASH->AR = (int) pdbs_config_array;
148
     /* Set the STRT bit in the FLASH_CR register to start the erasing */
148
     /* Set the STRT bit in the FLASH_CR register to start the erasing */
149
     FLASH->CR |= FLASH_CR_STRT;
149
     FLASH->CR |= FLASH_CR_STRT;
150
     /* Wait till no operation is on going */
150
     /* Wait till no operation is on going */
162
     FLASH->CR &= ~FLASH_CR_PER;
162
     FLASH->CR &= ~FLASH_CR_PER;
163
 }
163
 }
164
 
164
 
165
-void pdb_config_flash_erase(void)
165
+void pdbs_config_flash_erase(void)
166
 {
166
 {
167
     /* Enter a critical zone */
167
     /* Enter a critical zone */
168
     chSysLock();
168
     chSysLock();
181
     chSysUnlock();
181
     chSysUnlock();
182
 }
182
 }
183
 
183
 
184
-void pdb_config_flash_update(const struct pdb_config *cfg)
184
+void pdbs_config_flash_update(const struct pdbs_config *cfg)
185
 {
185
 {
186
     /* Enter a critical zone */
186
     /* Enter a critical zone */
187
     chSysLock();
187
     chSysLock();
189
     flash_unlock();
189
     flash_unlock();
190
 
190
 
191
     /* If there is an old entry, invalidate it. */
191
     /* If there is an old entry, invalidate it. */
192
-    struct pdb_config *old = pdb_config_flash_read();
192
+    struct pdbs_config *old = pdbs_config_flash_read();
193
     if (old != NULL) {
193
     if (old != NULL) {
194
-        flash_write_halfword(&(old->status), PDB_CONFIG_STATUS_INVALID);
194
+        flash_write_halfword(&(old->status), PDBS_CONFIG_STATUS_INVALID);
195
     }
195
     }
196
 
196
 
197
     /* Find the first empty entry */
197
     /* Find the first empty entry */
198
-    struct pdb_config *empty = NULL;
199
-    for (int i = 0; i < PDB_CONFIG_ARRAY_LEN; i++) {
198
+    struct pdbs_config *empty = NULL;
199
+    for (int i = 0; i < PDBS_CONFIG_ARRAY_LEN; i++) {
200
         /* If we've found it, return it. */
200
         /* If we've found it, return it. */
201
-        if (pdb_config_array[i].status == PDB_CONFIG_STATUS_EMPTY) {
202
-            empty = &pdb_config_array[i];
201
+        if (pdbs_config_array[i].status == PDBS_CONFIG_STATUS_EMPTY) {
202
+            empty = &pdbs_config_array[i];
203
             break;
203
             break;
204
         }
204
         }
205
     }
205
     }
207
     if (empty == NULL) {
207
     if (empty == NULL) {
208
         flash_erase();
208
         flash_erase();
209
         /* Write to the first element */
209
         /* Write to the first element */
210
-        empty = &pdb_config_array[0];
210
+        empty = &pdbs_config_array[0];
211
     }
211
     }
212
 
212
 
213
     /* Write the new configuration */
213
     /* Write the new configuration */
227
     chSysUnlock();
227
     chSysUnlock();
228
 }
228
 }
229
 
229
 
230
-struct pdb_config *pdb_config_flash_read(void)
230
+struct pdbs_config *pdbs_config_flash_read(void)
231
 {
231
 {
232
     /* If we already know where the configuration is, return its location */
232
     /* If we already know where the configuration is, return its location */
233
     if (config_cur != NULL) {
233
     if (config_cur != NULL) {
238
      * need to find it and store its location if applicable. */
238
      * need to find it and store its location if applicable. */
239
 
239
 
240
     /* If the first element is empty, there is no valid structure. */
240
     /* If the first element is empty, there is no valid structure. */
241
-    if (pdb_config_array[0].status == PDB_CONFIG_STATUS_EMPTY) {
241
+    if (pdbs_config_array[0].status == PDBS_CONFIG_STATUS_EMPTY) {
242
         return NULL;
242
         return NULL;
243
     }
243
     }
244
 
244
 
245
     /* Find the valid structure, if there is one. */
245
     /* Find the valid structure, if there is one. */
246
-    for (int i = 0; i < PDB_CONFIG_ARRAY_LEN; i++) {
246
+    for (int i = 0; i < PDBS_CONFIG_ARRAY_LEN; i++) {
247
         /* If we've found it, return it. */
247
         /* If we've found it, return it. */
248
-        if (pdb_config_array[i].status == PDB_CONFIG_STATUS_VALID) {
249
-            config_cur = &pdb_config_array[i];
248
+        if (pdbs_config_array[i].status == PDBS_CONFIG_STATUS_VALID) {
249
+            config_cur = &pdbs_config_array[i];
250
             return config_cur;
250
             return config_cur;
251
         }
251
         }
252
     }
252
     }

+ 12
- 12
src/config.h View File

27
 /*
27
 /*
28
  * PD Buddy Sink configuration structure
28
  * PD Buddy Sink configuration structure
29
  */
29
  */
30
-struct pdb_config {
30
+struct pdbs_config {
31
     uint16_t status;
31
     uint16_t status;
32
     uint16_t flags;
32
     uint16_t flags;
33
     uint16_t v;
33
     uint16_t v;
41
  * ready to be written, including a status update to VALID.  Once the struct is
41
  * ready to be written, including a status update to VALID.  Once the struct is
42
  * no longer needed, the status is updated to INVALID.  Erasing the flash page
42
  * no longer needed, the status is updated to INVALID.  Erasing the flash page
43
  * resets all structures to EMPTY. */
43
  * resets all structures to EMPTY. */
44
-#define PDB_CONFIG_STATUS_INVALID 0x0000
45
-#define PDB_CONFIG_STATUS_VALID 0xBEEF
46
-#define PDB_CONFIG_STATUS_EMPTY 0xFFFF
44
+#define PDBS_CONFIG_STATUS_INVALID 0x0000
45
+#define PDBS_CONFIG_STATUS_VALID 0xBEEF
46
+#define PDBS_CONFIG_STATUS_EMPTY 0xFFFF
47
 
47
 
48
 /* Flags for configuration structures. */
48
 /* Flags for configuration structures. */
49
 /* GiveBack supported */
49
 /* GiveBack supported */
50
-#define PDB_CONFIG_FLAGS_GIVEBACK 0x0001
50
+#define PDBS_CONFIG_FLAGS_GIVEBACK 0x0001
51
 /* Variable and battery PDOs supported (v_min and v_max valid) */
51
 /* Variable and battery PDOs supported (v_min and v_max valid) */
52
-#define PDB_CONFIG_FLAGS_VAR_BAT 0x0002
52
+#define PDBS_CONFIG_FLAGS_VAR_BAT 0x0002
53
 
53
 
54
 
54
 
55
 /* Flash configuration array */
55
 /* Flash configuration array */
56
-extern struct pdb_config *pdb_config_array;
56
+extern struct pdbs_config *pdbs_config_array;
57
 
57
 
58
 /* The number of elements in the pdb_config_array */
58
 /* The number of elements in the pdb_config_array */
59
-#define PDB_CONFIG_ARRAY_LEN 128
59
+#define PDBS_CONFIG_ARRAY_LEN 128
60
 
60
 
61
 
61
 
62
 /*
62
 /*
63
  * Print a struct pdb_config to the given BaseSequentialStream
63
  * Print a struct pdb_config to the given BaseSequentialStream
64
  */
64
  */
65
-void pdb_config_print(BaseSequentialStream *chp, const struct pdb_config *cfg);
65
+void pdbs_config_print(BaseSequentialStream *chp, const struct pdbs_config *cfg);
66
 
66
 
67
 /*
67
 /*
68
  * Erase the flash page used for configuration
68
  * Erase the flash page used for configuration
69
  */
69
  */
70
-void pdb_config_flash_erase(void);
70
+void pdbs_config_flash_erase(void);
71
 
71
 
72
 /*
72
 /*
73
  * Write a configuration structure to flash, invalidating the previous
73
  * Write a configuration structure to flash, invalidating the previous
74
  * configuration.  If necessary, the flash page is erased before writing the
74
  * configuration.  If necessary, the flash page is erased before writing the
75
  * new structure.
75
  * new structure.
76
  */
76
  */
77
-void pdb_config_flash_update(const struct pdb_config *cfg);
77
+void pdbs_config_flash_update(const struct pdbs_config *cfg);
78
 
78
 
79
 /*
79
 /*
80
  * Get the first valid configuration strucure.  If the flash page is empty,
80
  * Get the first valid configuration strucure.  If the flash page is empty,
85
  * lookup is only performed the first time this function is called, so there's
85
  * lookup is only performed the first time this function is called, so there's
86
  * very little penalty to calling it repeatedly.
86
  * very little penalty to calling it repeatedly.
87
  */
87
  */
88
-struct pdb_config *pdb_config_flash_read(void);
88
+struct pdbs_config *pdbs_config_flash_read(void);
89
 
89
 
90
 
90
 
91
 #endif /* PDB_CONFIG_H */
91
 #endif /* PDB_CONFIG_H */

+ 64
- 40
src/device_policy_manager.c View File

47
 /* The requested voltage */
47
 /* The requested voltage */
48
 static int dpm_requested_voltage;
48
 static int dpm_requested_voltage;
49
 
49
 
50
-bool pdb_dpm_evaluate_capability(const union pd_msg *capabilities, union pd_msg *request)
50
+/* Whether our capabilities matched or not */
51
+static bool dpm_capability_match;
52
+
53
+bool pdbs_dpm_evaluate_capability(struct pdb_config *cfg,
54
+        const union pd_msg *capabilities, union pd_msg *request)
51
 {
55
 {
52
     /* Update the stored Source_Capabilities */
56
     /* Update the stored Source_Capabilities */
53
     if (capabilities != NULL) {
57
     if (capabilities != NULL) {
61
     }
65
     }
62
 
66
 
63
     /* Get the current configuration */
67
     /* Get the current configuration */
64
-    struct pdb_config *cfg = pdb_config_flash_read();
68
+    struct pdbs_config *scfg = pdbs_config_flash_read();
65
     /* Get the number of PDOs */
69
     /* Get the number of PDOs */
66
     uint8_t numobj = PD_NUMOBJ_GET(capabilities);
70
     uint8_t numobj = PD_NUMOBJ_GET(capabilities);
67
 
71
 
74
     dpm_unconstrained_power = capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
78
     dpm_unconstrained_power = capabilities->obj[0] & PD_PDO_SRC_FIXED_UNCONSTRAINED;
75
 
79
 
76
     /* Make sure we have configuration */
80
     /* Make sure we have configuration */
77
-    if (cfg != NULL && pdb_dpm_output_enabled) {
81
+    if (scfg != NULL && pdb_dpm_output_enabled) {
78
         /* Look at the PDOs to see if one matches our desires */
82
         /* Look at the PDOs to see if one matches our desires */
79
         for (uint8_t i = 0; i < numobj; i++) {
83
         for (uint8_t i = 0; i < numobj; i++) {
80
             /* Fixed Supply PDOs come first, so when we see a PDO that isn't a
84
             /* Fixed Supply PDOs come first, so when we see a PDO that isn't a
84
             }
88
             }
85
             /* If the V from the PDO equals our desired V and the I is at least
89
             /* If the V from the PDO equals our desired V and the I is at least
86
              * our desired I */
90
              * our desired I */
87
-            if (PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities, i) == cfg->v
88
-                    && PD_PDO_SRC_FIXED_CURRENT_GET(capabilities, i) >= cfg->i) {
91
+            if (PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities, i) == scfg->v
92
+                    && PD_PDO_SRC_FIXED_CURRENT_GET(capabilities, i) >= scfg->i) {
89
                 /* We got what we wanted, so build a request for that */
93
                 /* We got what we wanted, so build a request for that */
90
                 request->hdr = PD_MSGTYPE_REQUEST | PD_DATAROLE_UFP |
94
                 request->hdr = PD_MSGTYPE_REQUEST | PD_DATAROLE_UFP |
91
                     PD_SPECREV_2_0 | PD_POWERROLE_SINK | PD_NUMOBJ(1);
95
                     PD_SPECREV_2_0 | PD_POWERROLE_SINK | PD_NUMOBJ(1);
92
-                if (cfg->flags & PDB_CONFIG_FLAGS_GIVEBACK) {
96
+                if (scfg->flags & PDBS_CONFIG_FLAGS_GIVEBACK) {
93
                     /* GiveBack enabled */
97
                     /* GiveBack enabled */
94
                     request->obj[0] = PD_RDO_FV_MIN_CURRENT_SET(DPM_MIN_CURRENT)
98
                     request->obj[0] = PD_RDO_FV_MIN_CURRENT_SET(DPM_MIN_CURRENT)
95
-                        | PD_RDO_FV_CURRENT_SET(cfg->i)
99
+                        | PD_RDO_FV_CURRENT_SET(scfg->i)
96
                         | PD_RDO_NO_USB_SUSPEND | PD_RDO_GIVEBACK
100
                         | PD_RDO_NO_USB_SUSPEND | PD_RDO_GIVEBACK
97
                         | PD_RDO_OBJPOS_SET(i + 1);
101
                         | PD_RDO_OBJPOS_SET(i + 1);
98
                 } else {
102
                 } else {
99
                     /* GiveBack disabled */
103
                     /* GiveBack disabled */
100
-                    request->obj[0] = PD_RDO_FV_MAX_CURRENT_SET(cfg->i)
101
-                        | PD_RDO_FV_CURRENT_SET(cfg->i)
104
+                    request->obj[0] = PD_RDO_FV_MAX_CURRENT_SET(scfg->i)
105
+                        | PD_RDO_FV_CURRENT_SET(scfg->i)
102
                         | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(i + 1);
106
                         | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(i + 1);
103
                 }
107
                 }
104
                 if (pdb_dpm_usb_comms) {
108
                 if (pdb_dpm_usb_comms) {
106
                 }
110
                 }
107
 
111
 
108
                 /* Update requested voltage */
112
                 /* Update requested voltage */
109
-                dpm_requested_voltage = cfg->v;
113
+                dpm_requested_voltage = scfg->v;
110
 
114
 
115
+                dpm_capability_match = true;
111
                 return true;
116
                 return true;
112
             }
117
             }
113
         }
118
         }
133
     dpm_requested_voltage = PD_MV2PDV(5000);
138
     dpm_requested_voltage = PD_MV2PDV(5000);
134
 
139
 
135
     /* At this point, we have a capability match iff the output is disabled */
140
     /* At this point, we have a capability match iff the output is disabled */
141
+    dpm_capability_match = !pdb_dpm_output_enabled;
136
     return !pdb_dpm_output_enabled;
142
     return !pdb_dpm_output_enabled;
137
 }
143
 }
138
 
144
 
139
-void pdb_dpm_get_sink_capability(union pd_msg *cap)
145
+void pdbs_dpm_get_sink_capability(struct pdb_config *cfg, union pd_msg *cap)
140
 {
146
 {
141
     /* Keep track of how many PDOs we've added */
147
     /* Keep track of how many PDOs we've added */
142
     int numobj = 0;
148
     int numobj = 0;
143
     /* Get the current configuration */
149
     /* Get the current configuration */
144
-    struct pdb_config *cfg = pdb_config_flash_read();
150
+    struct pdbs_config *scfg = pdbs_config_flash_read();
145
 
151
 
146
     /* If we have no configuration or want something other than 5 V, add a PDO
152
     /* If we have no configuration or want something other than 5 V, add a PDO
147
      * for vSafe5V */
153
      * for vSafe5V */
148
-    if (cfg == NULL || cfg->v != PD_MV2PDV(5000)) {
154
+    if (scfg == NULL || scfg->v != PD_MV2PDV(5000)) {
149
         /* Minimum current, 5 V, and higher capability. */
155
         /* Minimum current, 5 V, and higher capability. */
150
         cap->obj[numobj++] = PD_PDO_TYPE_FIXED
156
         cap->obj[numobj++] = PD_PDO_TYPE_FIXED
151
             | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(5000))
157
             | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(5000))
153
     }
159
     }
154
 
160
 
155
     /* Add a PDO for the desired power. */
161
     /* Add a PDO for the desired power. */
156
-    if (cfg != NULL) {
162
+    if (scfg != NULL) {
157
         cap->obj[numobj++] = PD_PDO_TYPE_FIXED
163
         cap->obj[numobj++] = PD_PDO_TYPE_FIXED
158
-            | PD_PDO_SNK_FIXED_VOLTAGE_SET(cfg->v)
159
-            | PD_PDO_SNK_FIXED_CURRENT_SET(cfg->i);
164
+            | PD_PDO_SNK_FIXED_VOLTAGE_SET(scfg->v)
165
+            | PD_PDO_SNK_FIXED_CURRENT_SET(scfg->i);
160
         /* If we want more than 5 V, set the Higher Capability flag */
166
         /* If we want more than 5 V, set the Higher Capability flag */
161
-        if (cfg->v != PD_MV2PDV(5000)) {
167
+        if (scfg->v != PD_MV2PDV(5000)) {
162
             cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
168
             cap->obj[0] |= PD_PDO_SNK_FIXED_HIGHER_CAP;
163
         }
169
         }
164
     }
170
     }
178
         | PD_POWERROLE_SINK | PD_NUMOBJ(numobj);
184
         | PD_POWERROLE_SINK | PD_NUMOBJ(numobj);
179
 }
185
 }
180
 
186
 
181
-bool pdb_dpm_giveback_enabled(void)
187
+bool pdbs_dpm_giveback_enabled(struct pdb_config *cfg)
182
 {
188
 {
183
-    struct pdb_config *cfg = pdb_config_flash_read();
189
+    struct pdbs_config *scfg = pdbs_config_flash_read();
184
 
190
 
185
-    return cfg->flags & PDB_CONFIG_FLAGS_GIVEBACK;
191
+    return scfg->flags & PDBS_CONFIG_FLAGS_GIVEBACK;
186
 }
192
 }
187
 
193
 
188
-bool pdb_dpm_evaluate_typec_current(enum fusb_typec_current tcc)
194
+bool pdbs_dpm_evaluate_typec_current(struct pdb_config *cfg,
195
+        enum fusb_typec_current tcc)
189
 {
196
 {
190
-    struct pdb_config *cfg = pdb_config_flash_read();
197
+    struct pdbs_config *scfg = pdbs_config_flash_read();
191
 
198
 
192
     /* We don't control the voltage anymore; it will always be 5 V. */
199
     /* We don't control the voltage anymore; it will always be 5 V. */
193
     dpm_requested_voltage = PD_MV2PDV(5000);
200
     dpm_requested_voltage = PD_MV2PDV(5000);
198
 
205
 
199
     /* If we have no configuration or don't want 5 V, Type-C Current can't
206
     /* If we have no configuration or don't want 5 V, Type-C Current can't
200
      * possibly satisfy our needs */
207
      * possibly satisfy our needs */
201
-    if (cfg == NULL || cfg->v != PD_MV2PDV(5000)) {
208
+    if (scfg == NULL || scfg->v != PD_MV2PDV(5000)) {
209
+        dpm_capability_match = false;
202
         return false;
210
         return false;
203
     }
211
     }
204
 
212
 
205
     /* If 1.5 A is available and we want no more than that, great. */
213
     /* If 1.5 A is available and we want no more than that, great. */
206
-    if (tcc == OnePointFiveAmps && cfg->i <= 150) {
214
+    if (tcc == OnePointFiveAmps && scfg->i <= 150) {
215
+        dpm_capability_match = true;
207
         return true;
216
         return true;
208
     }
217
     }
209
     /* If 3 A is available and we want no more than that, that's great too. */
218
     /* If 3 A is available and we want no more than that, that's great too. */
210
-    if (tcc == ThreePointZeroAmps && cfg->i <= 300) {
219
+    if (tcc == ThreePointZeroAmps && scfg->i <= 300) {
220
+        dpm_capability_match = true;
211
         return true;
221
         return true;
212
     }
222
     }
213
     /* We're overly cautious if USB default current is available, since that
223
     /* We're overly cautious if USB default current is available, since that
215
      * and since we're really supposed to enumerate in order to request more
225
      * and since we're really supposed to enumerate in order to request more
216
      * than 100 mA.  This could be changed in the future. */
226
      * than 100 mA.  This could be changed in the future. */
217
 
227
 
228
+    dpm_capability_match = false;
218
     return false;
229
     return false;
219
 }
230
 }
220
 
231
 
221
-void pdb_dpm_pd_start(void)
232
+void pdbs_dpm_pd_start(struct pdb_config *cfg)
222
 {
233
 {
223
     if (pdb_dpm_led_pd_status) {
234
     if (pdb_dpm_led_pd_status) {
224
         chEvtSignal(pdb_led_thread, PDB_EVT_LED_NEGOTIATING);
235
         chEvtSignal(pdb_led_thread, PDB_EVT_LED_NEGOTIATING);
225
     }
236
     }
226
 }
237
 }
227
 
238
 
228
-void pdb_dpm_sink_standby(void)
229
-{
230
-    /* If the voltage is changing, enter Sink Standby */
231
-    if (dpm_requested_voltage != dpm_present_voltage) {
232
-        /* For the PD Buddy Sink, entering Sink Standby is equivalent to
233
-         * turning the output off.  However, we don't want to change the LED
234
-         * state for standby mode. */
235
-        palClearLine(LINE_OUT_CTRL);
236
-    }
237
-}
238
-
239
-void pdb_dpm_output_set(bool state)
239
+/*
240
+ * Set the output state, with LED indication.
241
+ */
242
+static void dpm_output_set(bool state)
240
 {
243
 {
241
     /* Update the present voltage */
244
     /* Update the present voltage */
242
     dpm_present_voltage = dpm_requested_voltage;
245
     dpm_present_voltage = dpm_requested_voltage;
257
     }
260
     }
258
 }
261
 }
259
 
262
 
260
-void pdb_dpm_output_default(void)
263
+void pdbs_dpm_transition_default(struct pdb_config *cfg)
261
 {
264
 {
262
     /* Pretend we requested 5 V */
265
     /* Pretend we requested 5 V */
263
     dpm_requested_voltage = PD_MV2PDV(5000);
266
     dpm_requested_voltage = PD_MV2PDV(5000);
264
     /* Turn the output off */
267
     /* Turn the output off */
265
-    pdb_dpm_output_set(false);
268
+    dpm_output_set(false);
269
+}
270
+
271
+void pdbs_dpm_transition_min(struct pdb_config *cfg)
272
+{
273
+    dpm_output_set(false);
274
+}
275
+
276
+void pdbs_dpm_transition_standby(struct pdb_config *cfg)
277
+{
278
+    /* If the voltage is changing, enter Sink Standby */
279
+    if (dpm_requested_voltage != dpm_present_voltage) {
280
+        /* For the PD Buddy Sink, entering Sink Standby is equivalent to
281
+         * turning the output off.  However, we don't want to change the LED
282
+         * state for standby mode. */
283
+        palClearLine(LINE_OUT_CTRL);
284
+    }
285
+}
286
+
287
+void pdbs_dpm_transition_requested(struct pdb_config *cfg)
288
+{
289
+    dpm_output_set(dpm_capability_match);
266
 }
290
 }

+ 18
- 11
src/device_policy_manager.h View File

21
 
21
 
22
 #include <stdbool.h>
22
 #include <stdbool.h>
23
 
23
 
24
+#include <pdb.h>
24
 #include "fusb302b.h"
25
 #include "fusb302b.h"
25
 #include "messages.h"
26
 #include "messages.h"
26
 
27
 
48
  *
49
  *
49
  * Returns true if sufficient power is available, false otherwise.
50
  * Returns true if sufficient power is available, false otherwise.
50
  */
51
  */
51
-bool pdb_dpm_evaluate_capability(const union pd_msg *capabilities, union pd_msg *request);
52
+bool pdbs_dpm_evaluate_capability(struct pdb_config *cfg,
53
+        const union pd_msg *capabilities, union pd_msg *request);
52
 
54
 
53
 /*
55
 /*
54
  * Create a Sink_Capabilities message for our current capabilities.
56
  * Create a Sink_Capabilities message for our current capabilities.
55
  */
57
  */
56
-void pdb_dpm_get_sink_capability(union pd_msg *cap);
58
+void pdbs_dpm_get_sink_capability(struct pdb_config *cfg, union pd_msg *cap);
57
 
59
 
58
 /*
60
 /*
59
  * Return whether or not GiveBack support is enabled.
61
  * Return whether or not GiveBack support is enabled.
60
  */
62
  */
61
-bool pdb_dpm_giveback_enabled(void);
63
+bool pdbs_dpm_giveback_enabled(struct pdb_config *cfg);
62
 
64
 
63
 /*
65
 /*
64
  * Evaluate whether or not the currently offered Type-C Current can fulfill our
66
  * Evaluate whether or not the currently offered Type-C Current can fulfill our
66
  *
68
  *
67
  * Returns true if sufficient power is available, false otherwise.
69
  * Returns true if sufficient power is available, false otherwise.
68
  */
70
  */
69
-bool pdb_dpm_evaluate_typec_current(enum fusb_typec_current tcc);
71
+bool pdbs_dpm_evaluate_typec_current(struct pdb_config *cfg, enum fusb_typec_current tcc);
70
 
72
 
71
 /*
73
 /*
72
  * Indicate that power negotiations are starting.
74
  * Indicate that power negotiations are starting.
73
  */
75
  */
74
-void pdb_dpm_pd_start(void);
76
+void pdbs_dpm_pd_start(struct pdb_config *cfg);
75
 
77
 
76
 /*
78
 /*
77
- * Transition to Sink Standby if necessary.
79
+ * Transition the sink to default power.
78
  */
80
  */
79
-void pdb_dpm_sink_standby(void);
81
+void pdbs_dpm_transition_default(struct pdb_config *cfg);
80
 
82
 
81
 /*
83
 /*
82
- * Set the output state, with LED indication.
84
+ * Transition to the requested minimum current.
83
  */
85
  */
84
-void pdb_dpm_output_set(bool state);
86
+void pdbs_dpm_transition_min(struct pdb_config *cfg);
85
 
87
 
86
 /*
88
 /*
87
- * Transition the sink to default power.
89
+ * Transition to Sink Standby if necessary.
90
+ */
91
+void pdbs_dpm_transition_standby(struct pdb_config *cfg);
92
+
93
+/*
94
+ * Transition to the requested power level
88
  */
95
  */
89
-void pdb_dpm_output_default(void);
96
+void pdbs_dpm_transition_requested(struct pdb_config *cfg);
90
 
97
 
91
 
98
 
92
 #endif /* PDB_DEVICE_POLICY_MANAGER_H */
99
 #endif /* PDB_DEVICE_POLICY_MANAGER_H */

+ 24
- 2
src/main.c View File

56
     0
56
     0
57
 };
57
 };
58
 
58
 
59
+/*
60
+ * PD Buddy firmware library configuration object
61
+ */
62
+static struct pdb_config pdb_config = {
63
+    .fusb = {
64
+        &I2CD2,
65
+        FUSB302B_ADDR
66
+    },
67
+    .dpm = {
68
+        pdbs_dpm_evaluate_capability,
69
+        pdbs_dpm_get_sink_capability,
70
+        pdbs_dpm_giveback_enabled,
71
+        pdbs_dpm_evaluate_typec_current,
72
+        pdbs_dpm_pd_start,
73
+        pdbs_dpm_transition_default,
74
+        pdbs_dpm_transition_min,
75
+        pdbs_dpm_transition_standby,
76
+        pdbs_dpm_transition_requested,
77
+        pdbs_dpm_transition_requested /* XXX type-c current */
78
+    }
79
+};
80
+
59
 /*
81
 /*
60
  * Enter setup mode
82
  * Enter setup mode
61
  */
83
  */
67
     pdb_dpm_usb_comms = true;
89
     pdb_dpm_usb_comms = true;
68
 
90
 
69
     /* Start the USB Power Delivery threads */
91
     /* Start the USB Power Delivery threads */
70
-    pdb_init();
92
+    pdb_init(&pdb_config);
71
 
93
 
72
     /* Indicate that we're in setup mode */
94
     /* Indicate that we're in setup mode */
73
     chEvtSignal(pdb_led_thread, PDB_EVT_LED_CONFIG);
95
     chEvtSignal(pdb_led_thread, PDB_EVT_LED_CONFIG);
94
 static void sink(void)
116
 static void sink(void)
95
 {
117
 {
96
     /* Start the USB Power Delivery threads */
118
     /* Start the USB Power Delivery threads */
97
-    pdb_init();
119
+    pdb_init(&pdb_config);
98
 
120
 
99
     /* Wait, letting all the other threads do their work. */
121
     /* Wait, letting all the other threads do their work. */
100
     while (true) {
122
     while (true) {

+ 12
- 12
src/shell.c View File

48
 
48
 
49
 
49
 
50
 /* Buffer for unwritten configuration */
50
 /* Buffer for unwritten configuration */
51
-static struct pdb_config tmpcfg = {
52
-    .status = PDB_CONFIG_STATUS_VALID
51
+static struct pdbs_config tmpcfg = {
52
+    .status = PDBS_CONFIG_STATUS_VALID
53
 };
53
 };
54
 
54
 
55
 /*
55
 /*
162
         return;
162
         return;
163
     }
163
     }
164
 
164
 
165
-    pdb_config_flash_erase();
165
+    pdbs_config_flash_erase();
166
 }
166
 }
167
 
167
 
168
 static void cmd_write(BaseSequentialStream *chp, int argc, char *argv[])
168
 static void cmd_write(BaseSequentialStream *chp, int argc, char *argv[])
173
         return;
173
         return;
174
     }
174
     }
175
 
175
 
176
-    pdb_config_flash_update(&tmpcfg);
176
+    pdbs_config_flash_update(&tmpcfg);
177
 
177
 
178
     chEvtSignal(pdb_pe_thread, PDB_EVT_PE_NEW_POWER);
178
     chEvtSignal(pdb_pe_thread, PDB_EVT_PE_NEW_POWER);
179
 }
179
 }
187
     }
187
     }
188
 
188
 
189
     /* Get the current configuration */
189
     /* Get the current configuration */
190
-    struct pdb_config *cfg = pdb_config_flash_read();
190
+    struct pdbs_config *cfg = pdbs_config_flash_read();
191
     if (cfg == NULL) {
191
     if (cfg == NULL) {
192
         chprintf(chp, "No configuration\r\n");
192
         chprintf(chp, "No configuration\r\n");
193
         return;
193
         return;
204
 
204
 
205
 static void cmd_get_cfg(BaseSequentialStream *chp, int argc, char *argv[])
205
 static void cmd_get_cfg(BaseSequentialStream *chp, int argc, char *argv[])
206
 {
206
 {
207
-    struct pdb_config *cfg = NULL;
207
+    struct pdbs_config *cfg = NULL;
208
 
208
 
209
     if (argc > 1) {
209
     if (argc > 1) {
210
         chprintf(chp, "Usage: get_cfg [index]\r\n");
210
         chprintf(chp, "Usage: get_cfg [index]\r\n");
213
 
213
 
214
     /* With no arguments, find the current configuration */
214
     /* With no arguments, find the current configuration */
215
     if (argc == 0) {
215
     if (argc == 0) {
216
-        cfg = pdb_config_flash_read();
216
+        cfg = pdbs_config_flash_read();
217
         if (cfg == NULL) {
217
         if (cfg == NULL) {
218
             chprintf(chp, "No configuration\r\n");
218
             chprintf(chp, "No configuration\r\n");
219
             return;
219
             return;
222
     } else if (argc == 1) {
222
     } else if (argc == 1) {
223
         char *endptr;
223
         char *endptr;
224
         long i = strtol(argv[0], &endptr, 0);
224
         long i = strtol(argv[0], &endptr, 0);
225
-        if (i >= 0 && i < PDB_CONFIG_ARRAY_LEN && endptr > argv[0]) {
226
-            cfg = &pdb_config_array[i];
225
+        if (i >= 0 && i < PDBS_CONFIG_ARRAY_LEN && endptr > argv[0]) {
226
+            cfg = &pdbs_config_array[i];
227
         } else {
227
         } else {
228
             chprintf(chp, "Invalid index\r\n");
228
             chprintf(chp, "Invalid index\r\n");
229
             return;
229
             return;
230
         }
230
         }
231
     }
231
     }
232
     /* Print the configuration */
232
     /* Print the configuration */
233
-    pdb_config_print(chp, cfg);
233
+    pdbs_config_print(chp, cfg);
234
 }
234
 }
235
 
235
 
236
 static void cmd_get_tmpcfg(BaseSequentialStream *chp, int argc, char *argv[])
236
 static void cmd_get_tmpcfg(BaseSequentialStream *chp, int argc, char *argv[])
241
         return;
241
         return;
242
     }
242
     }
243
 
243
 
244
-    pdb_config_print(chp, &tmpcfg);
244
+    pdbs_config_print(chp, &tmpcfg);
245
 }
245
 }
246
 
246
 
247
 static void cmd_clear_flags(BaseSequentialStream *chp, int argc, char *argv[])
247
 static void cmd_clear_flags(BaseSequentialStream *chp, int argc, char *argv[])
265
     }
265
     }
266
 
266
 
267
     /* Toggle the GiveBack flag */
267
     /* Toggle the GiveBack flag */
268
-    tmpcfg.flags ^= PDB_CONFIG_FLAGS_GIVEBACK;
268
+    tmpcfg.flags ^= PDBS_CONFIG_FLAGS_GIVEBACK;
269
 }
269
 }
270
 
270
 
271
 static void cmd_set_v(BaseSequentialStream *chp, int argc, char *argv[])
271
 static void cmd_set_v(BaseSequentialStream *chp, int argc, char *argv[])

Loading…
Cancel
Save