Преглед на файлове

Support the new typec_virtual PDO

This commit adds support for the new, yet-to-be-released typec_virtual
PDO reported from the firmware.  This was done by adding a
TypeCVirtualPDO class, code to load them from text, and support for them
in the calculation functions.  New tests have been written for all the
new code as well.
Clara Hobbs преди 6 години
родител
ревизия
fbd48c6b16
променени са 2 файла, в които са добавени 63 реда и са изтрити 1 реда
  1. 38
    0
      pdbuddy/__init__.py
  2. 25
    1
      test_pdbuddy/__init__.py

+ 38
- 0
pdbuddy/__init__.py Целия файл

@@ -381,6 +381,24 @@ class SrcFixedPDO(namedtuple("SrcFixedPDO", "dual_role_pwr usb_suspend "
381 381
         return s
382 382
 
383 383
 
384
+class TypeCVirtualPDO(namedtuple("TypeCVirtualPDO", "i")):
385
+    """A Type-C Current Virtual PDO
386
+
387
+    ``i`` is the advertised current in milliamperes.
388
+    """
389
+    __slots__ = ()
390
+
391
+    pdo_type = "typec_virtual"
392
+
393
+    def __str__(self):
394
+        """Print the TypeCVirtualPDO in the manner of the configuration shell"""
395
+        s = self.pdo_type + "\n"
396
+
397
+        s += "\ti: {:.2f} A".format(self.i / 1000.0)
398
+
399
+        return s
400
+
401
+
384 402
 def read_pdo(text):
385 403
     """Create a PDO object from partial text returned by Sink.send_command"""
386 404
     # First, determine the PDO type
@@ -427,6 +445,17 @@ def read_pdo(text):
427 445
                 peak_i=peak_i,
428 446
                 v=v,
429 447
                 i=i)
448
+    elif pdo_type == TypeCVirtualPDO.pdo_type:
449
+        # Load a TypeCVirtualPDO
450
+        for line in text[1:]:
451
+            fields = line.split(b":")
452
+            fields[0] = fields[0].strip()
453
+            fields[1] = fields[1].strip()
454
+            if fields[0] == b"i":
455
+                i = round(1000*float(fields[1].split()[0]))
456
+
457
+        # Make the TypeCVirtualPDO
458
+        return TypeCVirtualPDO(i=i)
430 459
     elif pdo_type == "No Source_Capabilities":
431 460
         return None
432 461
     else:
@@ -468,6 +497,8 @@ def calculate_pdp(pdo_list):
468 497
     for pdo in pdo_list:
469 498
         if pdo.pdo_type == "fixed":
470 499
             max_power = max(max_power, pdo.v / 1000.0 * pdo.i / 1000.0)
500
+        elif pdo.pdo_type == "typec_virtual":
501
+            max_power = max(max_power, 5.0 * pdo.i / 1000.0)
471 502
 
472 503
     return max_power
473 504
 
@@ -482,6 +513,13 @@ def follows_power_rules(pdo_list):
482 513
     # First, estimate the PDP assuming the rules are being followed
483 514
     pdp = calculate_pdp(pdo_list)
484 515
 
516
+    # If there's a typec_virtual PDO, there's no Power Delivery so the Power
517
+    # Rules cannot be violated.  In truth they're not really being followed
518
+    # either since they only apply to Power Delivery, but returning True here
519
+    # seems like the safer option.
520
+    if pdo_list and pdo_list[0].pdo_type == "typec_virtual":
521
+        return True
522
+
485 523
     # Make sure nothing exceeds the PDP
486 524
     for pdo in pdo_list:
487 525
         if pdo.pdo_type == "fixed":

+ 25
- 1
test_pdbuddy/__init__.py Целия файл

@@ -277,6 +277,15 @@ class SrcFixedPDOTestCase(unittest.TestCase):
277 277
                 "fixed\n\tv: 5.00 V\n\ti: 1.50 A")
278 278
 
279 279
 
280
+class TypeCVirtualPDOTestCase(unittest.TestCase):
281
+
282
+    def setUp(self):
283
+        self.obj_1p5a = pdbuddy.TypeCVirtualPDO(1500)
284
+
285
+    def test_str_1p5a(self):
286
+        self.assertEqual(str(self.obj_1p5a), "typec_virtual\n\ti: 1.50 A")
287
+
288
+
280 289
 class ReadPDOTestCase(unittest.TestCase):
281 290
 
282 291
     def setUp(self):
@@ -286,6 +295,7 @@ class ReadPDOTestCase(unittest.TestCase):
286 295
                 False, False, 0, 5000, 1500)
287 296
         self.unknown_zero = pdbuddy.UnknownPDO(value=0x00000000)
288 297
         self.unknown_notzero = pdbuddy.UnknownPDO(value=0xFFFFFFFF)
298
+        self.typec_virtual = pdbuddy.TypeCVirtualPDO(1500)
289 299
 
290 300
     def test_read_src_fixed_everything(self):
291 301
         rp_src_fixed_everything = pdbuddy.read_pdo([b"PDO 1: fixed",
@@ -319,6 +329,11 @@ class ReadPDOTestCase(unittest.TestCase):
319 329
         rp_unknown_notzero = pdbuddy.read_pdo([b"PDO 1: FFFFFFFF"])
320 330
         self.assertEqual(self.unknown_notzero, rp_unknown_notzero)
321 331
 
332
+    def test_read_typec_virtual(self):
333
+        rp_typec_virtual = pdbuddy.read_pdo([b"PDO 5: typec_virtual",
334
+                b"\ti: 1.50 A"])
335
+        self.assertEqual(self.typec_virtual, rp_typec_virtual)
336
+
322 337
     def test_read_none(self):
323 338
         none_pdo = pdbuddy.read_pdo([b"No Source_Capabilities"])
324 339
         self.assertEqual(none_pdo, None)
@@ -333,6 +348,7 @@ class ReadPDOListTestCase(unittest.TestCase):
333 348
                 False, False, 0, 5000, 1500)
334 349
         self.unknown_zero = pdbuddy.UnknownPDO(value=0x00000000)
335 350
         self.unknown_notzero = pdbuddy.UnknownPDO(value=0xFFFFFFFF)
351
+        self.typec_virtual = pdbuddy.TypeCVirtualPDO(1500)
336 352
 
337 353
     def test_read_pdo_list(self):
338 354
         # It's not a legal list for USB Power Delivery, but it works fine for
@@ -350,13 +366,16 @@ class ReadPDOListTestCase(unittest.TestCase):
350 366
                 b"\tv: 5.00 V",
351 367
                 b"\ti: 1.50 A",
352 368
                 b"PDO 3: 00000000",
353
-                b"PDO 4: FFFFFFFF"]
369
+                b"PDO 4: FFFFFFFF",
370
+                b"PDO 5: typec_virtual",
371
+                b"\ti: 1.50 A"]
354 372
         pdo_list = pdbuddy.read_pdo_list(text)
355 373
 
356 374
         self.assertEqual(pdo_list[0], self.src_fixed_everything)
357 375
         self.assertEqual(pdo_list[1], self.src_fixed_minimal)
358 376
         self.assertEqual(pdo_list[2], self.unknown_zero)
359 377
         self.assertEqual(pdo_list[3], self.unknown_notzero)
378
+        self.assertEqual(pdo_list[4], self.typec_virtual)
360 379
 
361 380
 
362 381
 class PDOListCalculationsTestCase(unittest.TestCase):
@@ -382,6 +401,10 @@ class PDOListCalculationsTestCase(unittest.TestCase):
382 401
                 False, False, 0, 20000, 2250)
383 402
         self.src_fixed_20v_5a = pdbuddy.SrcFixedPDO(False, False, False, False,
384 403
                 False, 0, 20000, 5000)
404
+        self.typec_virtual_1p5a = pdbuddy.TypeCVirtualPDO(1500)
405
+
406
+    def test_calculate_pdp_typec_virtual(self):
407
+        self.assertEqual(pdbuddy.calculate_pdp([self.typec_virtual_1p5a]), 7.5)
385 408
 
386 409
     def test_calculate_pdp_15w(self):
387 410
         self.assertEqual(pdbuddy.calculate_pdp([self.src_fixed_5v_3a]), 15)
@@ -411,6 +434,7 @@ class PDOListCalculationsTestCase(unittest.TestCase):
411 434
     def test_follows_power_rules_true(self):
412 435
         # <= 15 W
413 436
         self.assertTrue(pdbuddy.follows_power_rules([]))
437
+        self.assertTrue(pdbuddy.follows_power_rules([self.typec_virtual_1p5a]))
414 438
         self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_1p5a]))
415 439
         self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a]))
416 440
         self.assertTrue(pdbuddy.follows_power_rules([self.src_fixed_5v_3a,

Loading…
Отказ
Запис