forked from ZeroPhone/ZeroPhone-LowLevel-API-Python
/
zerophone_hw.py
169 lines (137 loc) · 5.28 KB
/
zerophone_hw.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env python
__all__ = ['get_hw_version_str', 'is_charging', 'RGB_LED', 'USB_DCDC', "GSM_Modem"]
__version__ = '0.3.0'
import sys
import gpio
from time import sleep
from copy import copy
sys.excepthook = sys.__excepthook__
#GPIO library workaround - it sets excepthook
#to PDB debug, that's good but it's going to
#propagate through pyLCI code, and that's not good
gpio.log.setLevel(gpio.logging.INFO)
#Otherwise, a bunch of stuff is printed on the screen
def get_hw_version_str():
#Only version there is for now =)
#Next implementations will probably be getting version strings from onboard EEPROM
return "gamma"
def is_charging():
hw_v = get_hw_version_str()
if hw_v == "gamma":
chg_sense_gpio = 503
gpio.setup(chg_sense_gpio, gpio.IN)
return bool(gpio.input(chg_sense_gpio))
else:
raise NotImplementedException("Version not supported!")
class USB_DCDC():
gpio_exported = False
gpio_state = None
switch_types = {
"gamma":"gpio_inverted"}
def __init__(self):
self.hw_v = get_hw_version_str()
self.gpio_num = self.get_gpio_num()
def get_gpio_num(self):
if self.hw_v == "gamma":
return 510
else:
raise NotImplementedException("Hardware version not supported!")
def set_state(self, state):
if not self.gpio_exported:
gpio.setup(self.gpio_num, gpio.OUT)
self.gpio_exported = True
self.gpio_state = state
if self.switch_types[self.hw_v] == "gpio_inverted":
gpio.set(self.gpio_num, not state)
elif self.switch_types[self.hw_v] == "gpio":
gpio.set(self.gpio_num, state)
else:
raise NotImplementedException("DC-DC switch type not supported!")
def on(self):
self.set_state(True)
def off(self):
self.set_state(False)
def toggle(self):
self.set_state(not self.gpio_state)
class GSM_Modem():
gpio_dict = {"exported":False, "state":None, "num":None}
gpio_names = ["ring", "reset", "dtr"]
gpio_nums = { "gamma":{"ring":501, "dtr":500, "reset":502} }
def __init__(self):
self.hw_v = get_hw_version_str()
self.set_gpio_nums()
def set_gpio_nums(self):
self.gpios = {name:copy(self.gpio_dict) for name in self.gpio_names}
if self.hw_v not in self.gpio_nums:
raise NotImplementedException("Hardware version not supported!")
gpio_nums = self.gpio_nums[self.hw_v]
for name, num in gpio_nums.items():
self.gpios[name]["num"] = num
def set_state(self, name, state):
g = self.gpios[name]
gpio_num = g["num"]
if not g["exported"]:
gpio.setup(gpio_num, gpio.OUT)
g["exported"] = True
g["state"] = state
gpio.set(gpio_num, state)
def reset(self):
self.set_state("reset", False)
sleep(1)
self.set_state("reset", True)
#TODO: add "get_ring_state" and "get_dtr_state" high-level functions
class RGB_LED():
color_mapping = {
"white": (255, 255, 255),
"red": (255, 0, 0),
"green": ( 0, 255, 0),
"blue": ( 0, 0, 255),
"none": ( 0, 0, 0)}
led_types = {
"gamma":"gpio_inverted"}
def __init__(self):
self.hw_v = get_hw_version_str()
self.led_type = self.get_led_type(self.hw_v)
self.setup()
def get_led_type(self, version):
if version in self.led_types:
return self.led_types[version]
else:
raise NotImplementedException("Hardware version not supported!")
def setup(self):
if self.led_type in ["gpio", "gpio_inverted"]:
for gpio_num in self.get_rgb_gpios():
gpio.setup(gpio_num, gpio.HIGH)
def get_rgb_gpios(self):
#returns GPIOs for red, green, blue
if self.hw_v == "gamma":
return (498, 496, 497)
else:
raise NotImplementedException("Hardware version not supported!")
def set_color(self, color_str):
try:
self.set_rgb(*self.color_mapping[color_str])
except KeyError:
raise ArgumentError("Color {} not found in color mapping!".format(color_str))
def set_rgb(self, *colors):
if len(colors) != 3 or any([type(color)!=int for color in colors]):
raise TypeError("set_rgb expects three integer arguments - red, green and blue values!")
if any([color<0 or color>255 for color in colors]):
raise ValueError("set_rgb expects integers in range from 0 to 255!")
if self.led_type in ["gpio", "gpio_inverted"]: #HW versions that have GPIO-controlled LED
gpios = self.get_rgb_gpios()
for i, gpio_num in enumerate(gpios):
gpio_state = colors[i]>0 #Only 0 and 255 are respected
if self.led_type == "gpio_inverted": gpio_state = not gpio_state
gpio.set(gpio_num, gpio_state)
else:
raise NotImplementedException("LED control type not supported!")
def __getattr__(self, name):
if name in self.color_mapping:
return lambda x=name: self.set_color(x)
if __name__ == "__main__":
led = RGB_LED()
dcdc = USB_DCDC()
while True:
print(is_charging())
sleep(1)