1#!/usr/bin/env python3

2# Copyright 2016-2020 Canonical Ltd.

3# All rights reserved.

4#

5# Written by:

6# Authors: Gavin Lin <gavin.lin@canonical.com>

7# Sylvain Pineau <sylvain.pineau@canonical.com>

8# Jonathan Cave <jonathan.cave@canonical.com>

9

10"""

11 This script will check number of detected I2C buses or devices

12

13 To see how to use, please run "./i2c_driver_test.py"

14"""

15

16 import argparse

17 import os

18 import subprocess

19

20

21 class Bus:

22 """Detect I2C bus."""

23

24 def invoked(self, args):

25 """Method called when the command is invoked."""

26 # Detect I2C buses and calculate number of them

27 result = subprocess.check_output(

28 ["i2cdetect", "-l"], universal_newlines=True

29 )

30 print(result)

31 bus_number = len(result.splitlines())

32 print("Detected bus number: {}".format(bus_number))

33

34 # Test failed if no I2C bus detected

35 if bus_number == 0:

36 raise SystemExit("Test failed, no bus detected.")

37

38 # Verify if detected number of buses is as expected

39 else:

40 if args.bus != 0:

41 if bus_number == args.bus:

42 print("Test passed")

43 else:

44 raise SystemExit(

45 "Test failed, expecting {} I2C "

46 "buses.".format(args.bus)

47 )

48

49

50 class Device:

51 """Detect I2C device."""

52

53 def invoked(self, args):

54 # Make sure that we have root privileges

55 if os.geteuid() != 0:

56 raise SystemExit("Error: please run this command as root")

57 # Calculate number of buses

58 result = subprocess.check_output(

59 ["i2cdetect", "-l"], universal_newlines=True

60 )

61 detected_i2c_bus = []

62 for line in result.splitlines():

63 detected_i2c_bus.append(line.split("\t")[0].split("-")[1])

64 print("Detected buses: {}".format(detected_i2c_bus))

65

66 # Detect device on each bus

67 exit_code = 1

68 for i in detected_i2c_bus:

69 print("Checking I2C bus {}".format(i))

70 result = subprocess.check_output(

71 ["i2cdetect", "-y", "-r", str(i)], universal_newlines=True

72 )

73 print(result)

74 result_lines = result.splitlines()[1:]

75 for r in result_lines:

76 address_value = r.strip("\n").split(":")[1].split()

77 for v in address_value:

78 if v != "--":

79 exit_code = 0

80 if exit_code == 1:

81 raise SystemExit("No I2C device detected on any I2C bus")

82 print("I2C device detected")

83

84

85 class I2cDriverTest:

86 """I2C driver test."""

87

88 def main(self):

89 subcommands = {"bus": Bus, "device": Device}

90 parser = argparse.ArgumentParser()

91 parser.add_argument("subcommand", type=str, choices=subcommands)

92 parser.add_argument(

93 "-b",

94 "--bus",

95 type=int,

96 default=0,

97 help="Expected number of I2C bus.",

98 )

99 args = parser.parse_args()

100 subcommands[args.subcommand]().invoked(args)

101

102

103 if __name__ == "__main__":

104 I2cDriverTest().main()