-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathi2c_test2.py
More file actions
113 lines (107 loc) · 4.04 KB
/
i2c_test2.py
File metadata and controls
113 lines (107 loc) · 4.04 KB
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
### main.py
import time
import picosleep
from machine import Pin, RTC, ADC
from i2c_responder import I2CResponder
from struct import pack, unpack
adc = ADC(Pin(28)) # main battery voltage measurement
rtc = RTC()
pwr = Pin(22, Pin.OUT, value=1) # wide-input enable, high for power on
led = Pin(25, Pin.OUT, value=1)
# When using ADC pins for I2C we need to turn on the pull-ups
sda = Pin(26, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
scl = Pin(27, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
i2c_responder = I2CResponder(1, sda_gpio=26, scl_gpio=27, responder_address=0x41)
status = 0x42
do_prt = False
def sleep(interval_s):
""
reason = 0 #wake_reason()
if do_prt:
print("Sleeping for", interval_s, "s...")
# turn the pull-ups off to conserve power
# sda.init(Pin.IN, None)
# scl.init(Pin.IN, None)
led.off()
time.sleep(1) # allow messages to get out before we stop the clocks
while interval_s > 0:
if do_prt:
time.sleep(1)
else:
picosleep.seconds(2)
led.on()
time.sleep_ms(2)
led.off()
interval_s -= 1
time.sleep(4)
led.on()
# turn the pull-ups back on
# sda.init(Pin.IN, Pin.PULL_UP)
# scl.init(Pin.IN, Pin.PULL_UP)
if do_prt:
print("...wakeup, reason =", reason)
return reason
try:
print("Polling I2C")
prefix_reg = 0
# All times are in milliseconds(?)
ticks_base = time.ticks_ms()
ticks_timeout = 40000
sleep_interval = 20
sleep(1)
while True:
# Poll for I2C writes
if i2c_responder.write_data_is_available():
buffer_in = i2c_responder.get_write_bytes(max_size=16)
if len(buffer_in) >= 1: # received some data
prefix_reg = buffer_in[0] # first byte must be a register number
data = buffer_in[1:] # copy the tail of the buffer
if data: # buffer tail wasn't empty
if do_prt:
print("Received I2C WRITE: reg =", prefix_reg, "data =", data, "len =", len(data))
# Poll for I2C reads
if i2c_responder.read_is_pending():
if prefix_reg == 1: # status register + watchdog reset
ticks_base = time.ticks_ms() # reset watchdog time base
data = status.to_bytes(1, 'little')
assert(len(data) == 1)
if do_prt:
print("Status")
elif prefix_reg == 2: # ADC value
data = adc.read_u16().to_bytes(2,'little')
assert(len(data) == 2)
if do_prt:
print("ADC")
elif prefix_reg == 3: # RTC date/time
data = pack("HBBBBBBH", *rtc.datetime())
assert(len(data) == 10)
if do_prt:
print("RTC")
elif prefix_reg == 4: # status register read and clear
data = status.to_bytes(1, 'little')
assert(len(data) == 1)
status = 0
if do_prt:
print("Status read and cleared")
else: # return a zero byte for all unrecognised regs
data = b'\x00'
assert(len(data) == 1)
if do_prt:
print("Default")
i2c_responder.put_read_bytes(data)
if do_prt:
print("Sent I2C READ data for register", prefix_reg)
prefix_reg = 0
if do_prt:
print()
# Check for watchdog timeout
ticks_now = time.ticks_ms()
ticks_interval = time.ticks_diff(ticks_now, ticks_base)
if ticks_timeout != 0 and ticks_interval >= ticks_timeout: # timeout set and reached
# This is where we would cut the power to the Pi
if do_prt:
print("Watchdog timeout exceeded: timeout =", ticks_timeout, "interval =", ticks_interval);
sleep(sleep_interval)
ticks_base = time.ticks_ms()
except KeyboardInterrupt:
pass