Browse Source

Make requests from PPS APDOs

PPS APDOs are second priority, behind fixed supply PDOs.
Clara Hobbs 6 years ago
parent
commit
6e1c09f649
2 changed files with 64 additions and 8 deletions
  1. 35
    0
      lib/include/pd.h
  2. 29
    8
      src/device_policy_manager.c

+ 35
- 0
lib/include/pd.h View File

177
 /* PD Source Fixed PDO voltage */
177
 /* PD Source Fixed PDO voltage */
178
 #define PD_PDO_SRC_FIXED_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_PDO_SRC_FIXED_VOLTAGE) >> PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
178
 #define PD_PDO_SRC_FIXED_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_PDO_SRC_FIXED_VOLTAGE) >> PD_PDO_SRC_FIXED_VOLTAGE_SHIFT)
179
 
179
 
180
+/* PD Source Programmable Power Supply APDO */
181
+#define PD_APDO_SRC_PPS_MAX_VOLTAGE_SHIFT 17
182
+#define PD_APDO_SRC_PPS_MAX_VOLTAGE (0xFF << PD_APDO_SRC_PPS_MAX_VOLTAGE_SHIFT)
183
+#define PD_APDO_SRC_PPS_MIN_VOLTAGE_SHIFT 8
184
+#define PD_APDO_SRC_PPS_MIN_VOLTAGE (0xFF << PD_APDO_SRC_PPS_MIN_VOLTAGE_SHIFT)
185
+#define PD_APDO_SRC_PPS_CURRENT_SHIFT 0
186
+#define PD_APDO_SRC_PPS_CURRENT (0x7F << PD_APDO_SRC_PPS_CURRENT_SHIFT)
187
+
188
+/* PD Source Programmable Power Supply APDO voltages */
189
+#define PD_APDO_SRC_PPS_MAX_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_APDO_SRC_PPS_MAX_VOLTAGE) >> PD_APDO_SRC_PPS_MAX_VOLTAGE_SHIFT)
190
+#define PD_APDO_SRC_PPS_MIN_VOLTAGE_GET(msg, i) (((msg)->obj[(i)] & PD_APDO_SRC_PPS_MIN_VOLTAGE) >> PD_APDO_SRC_PPS_MIN_VOLTAGE_SHIFT)
191
+
192
+/* PD Source Programmable Power Supply APDO current */
193
+#define PD_APDO_SRC_PPS_CURRENT_GET(msg, i) (((msg)->obj[(i)] & PD_APDO_SRC_PPS_CURRENT) >> PD_APDO_SRC_PPS_CURRENT_SHIFT)
194
+
180
 /* TODO: other types of source PDO */
195
 /* TODO: other types of source PDO */
181
 
196
 
182
 /* PD Sink Fixed PDO */
197
 /* PD Sink Fixed PDO */
240
 
255
 
241
 /* TODO: Battery RDOs */
256
 /* TODO: Battery RDOs */
242
 
257
 
258
+/* Programmable RDO */
259
+#define PD_RDO_PROG_VOLTAGE_SHIFT 9
260
+#define PD_RDO_PROG_VOLTAGE (0x7FF << PD_RDO_PROG_VOLTAGE_SHIFT)
261
+#define PD_RDO_PROG_CURRENT_SHIFT 0
262
+#define PD_RDO_PROG_CURRENT (0x7F << PD_RDO_PROG_CURRENT_SHIFT)
263
+
264
+#define PD_RDO_PROG_VOLTAGE_SET(i) (((i) << PD_RDO_PROG_VOLTAGE_SHIFT) & PD_RDO_PROG_VOLTAGE)
265
+#define PD_RDO_PROG_CURRENT_SET(i) (((i) << PD_RDO_PROG_CURRENT_SHIFT) & PD_RDO_PROG_CURRENT)
266
+
243
 
267
 
244
 /*
268
 /*
245
  * Time values
269
  * Time values
278
  * V: volt
302
  * V: volt
279
  * CV: centivolt
303
  * CV: centivolt
280
  * MV: millivolt
304
  * MV: millivolt
305
+ * PRV: Programmable RDO voltage unit (20 mV)
281
  * PDV: Power Delivery voltage unit (50 mV)
306
  * PDV: Power Delivery voltage unit (50 mV)
307
+ * PAV: PPS APDO voltage unit (100 mV)
282
  * A: ampere
308
  * A: ampere
283
  * CA: centiampere
309
  * CA: centiampere
284
  * MA: milliampere
310
  * MA: milliampere
285
  * PDI: Power Delivery current unit (10 mA)
311
  * PDI: Power Delivery current unit (10 mA)
312
+ * PAI: PPS APDO current unit (50 mA)
286
  */
313
  */
314
+#define PD_MV2PRV(mv) ((mv) / 20)
287
 #define PD_MV2PDV(mv) ((mv) / 50)
315
 #define PD_MV2PDV(mv) ((mv) / 50)
316
+#define PD_MV2PAV(mv) ((mv) / 100)
317
+#define PD_PRV2MV(prv) ((prv) * 20)
288
 #define PD_PDV2MV(pdv) ((pdv) * 50)
318
 #define PD_PDV2MV(pdv) ((pdv) * 50)
319
+#define PD_PAV2MV(pav) ((pav) * 100)
289
 #define PD_MA2PDI(ma) ((ma) / 10)
320
 #define PD_MA2PDI(ma) ((ma) / 10)
321
+#define PD_MA2PAI(ma) ((ma) / 50)
322
+#define PD_CA2PAI(ca) ((ca) / 5)
290
 #define PD_PDI2MA(pdi) ((pdi) * 10)
323
 #define PD_PDI2MA(pdi) ((pdi) * 10)
324
+#define PD_PAI2MA(pai) ((pai) * 50)
325
+#define PD_PAI2CA(pai) ((pai) * 5)
291
 
326
 
292
 /* Get portions of a voltage in more normal units */
327
 /* Get portions of a voltage in more normal units */
293
 #define PD_MV_V(mv) ((mv) / 1000)
328
 #define PD_MV_V(mv) ((mv) / 1000)

+ 29
- 8
src/device_policy_manager.c View File

65
     if (scfg != NULL && dpm_data->output_enabled) {
65
     if (scfg != NULL && dpm_data->output_enabled) {
66
         /* Look at the PDOs to see if one matches our desires */
66
         /* Look at the PDOs to see if one matches our desires */
67
         for (uint8_t i = 0; i < numobj; i++) {
67
         for (uint8_t i = 0; i < numobj; i++) {
68
-            /* Fixed Supply PDOs come first, so when we see a PDO that isn't a
69
-             * Fixed Supply, stop reading. */
70
-            if ((capabilities->obj[i] & PD_PDO_TYPE) != PD_PDO_TYPE_FIXED) {
71
-                break;
72
-            }
73
-            /* If the V from the PDO equals our desired V and the I is at least
74
-             * our desired I */
75
-            if (PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities, i) == PD_MV2PDV(scfg->v)
68
+            /* If we have a fixed PDO, its V equals our desired V, and its I is
69
+             * at least our desired I */
70
+            if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED
71
+                    && PD_PDO_SRC_FIXED_VOLTAGE_GET(capabilities, i) == PD_MV2PDV(scfg->v)
76
                     && PD_PDO_SRC_FIXED_CURRENT_GET(capabilities, i) >= scfg->i) {
72
                     && PD_PDO_SRC_FIXED_CURRENT_GET(capabilities, i) >= scfg->i) {
77
                 /* We got what we wanted, so build a request for that */
73
                 /* We got what we wanted, so build a request for that */
78
                 request->hdr = cfg->pe.hdr_template | PD_MSGTYPE_REQUEST
74
                 request->hdr = cfg->pe.hdr_template | PD_MSGTYPE_REQUEST
96
                 /* Update requested voltage */
92
                 /* Update requested voltage */
97
                 dpm_data->_requested_voltage = PD_PDV2MV(PD_MV2PDV(scfg->v));
93
                 dpm_data->_requested_voltage = PD_PDV2MV(PD_MV2PDV(scfg->v));
98
 
94
 
95
+                dpm_data->_capability_match = true;
96
+                return true;
97
+            }
98
+            /* If we have a PPS APDO, our desired V lies within its range, and
99
+             * its I is at least our desired I */
100
+            if ((capabilities->obj[i] & PD_PDO_TYPE) == PD_PDO_TYPE_AUGMENTED
101
+                    && (capabilities->obj[i] & PD_APDO_TYPE) == PD_APDO_TYPE_PPS
102
+                    && PD_APDO_SRC_PPS_MAX_VOLTAGE_GET(capabilities, i) >= PD_MV2PAV(scfg->v)
103
+                    && PD_APDO_SRC_PPS_MIN_VOLTAGE_GET(capabilities, i) <= PD_MV2PAV(scfg->v)
104
+                    && PD_APDO_SRC_PPS_CURRENT_GET(capabilities, i) >= PD_CA2PAI(scfg->i)) {
105
+                /* We got what we wanted, so build a request for that */
106
+                request->hdr = cfg->pe.hdr_template | PD_MSGTYPE_REQUEST
107
+                    | PD_NUMOBJ(1);
108
+
109
+                /* Build a request */
110
+                request->obj[0] = PD_RDO_PROG_CURRENT_SET(PD_CA2PAI(scfg->i))
111
+                    | PD_RDO_PROG_VOLTAGE_SET(PD_MV2PRV(scfg->v))
112
+                    | PD_RDO_NO_USB_SUSPEND | PD_RDO_OBJPOS_SET(i + 1);
113
+                if (dpm_data->usb_comms) {
114
+                    request->obj[0] |= PD_RDO_USB_COMMS;
115
+                }
116
+
117
+                /* Update requested voltage */
118
+                dpm_data->_requested_voltage = PD_PRV2MV(PD_MV2PRV(scfg->v));
119
+
99
                 dpm_data->_capability_match = true;
120
                 dpm_data->_capability_match = true;
100
                 return true;
121
                 return true;
101
             }
122
             }

Loading…
Cancel
Save