-
Notifications
You must be signed in to change notification settings - Fork 0
/
prtc.py
133 lines (112 loc) · 3.39 KB
/
prtc.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
# utility functions for Papirus Hat hardware clock (MCP7940N)
from __future__ import division
from datetime import datetime
from calendar import isleap
from smbusf import SMBus
RTCADR = 0x6f
STBIT = 0x80
LPYR = 0x20
almbase = [0xa, 0x11]
def tobcd(val):
return (val % 10) | (val // 10) << 4
def writertc(i2cbus, dt):
sec = dt.second
min = dt.minute
hour = dt.hour
# rtc-ds1307 uses weekday convention Sun = 1, Sat = 7
wkday = (dt.weekday() + 1)%7 + 1
day = dt.day
month = dt.month
year = dt.year
leap = isleap(year)
data = [0,0,0,0,0,0,0]
data[0] = tobcd(sec) | STBIT
data[1] = tobcd(min)
data[2] = tobcd(hour)
bits345 = i2cbus.read_byte_data(RTCADR, 3) & 0x38
data[3] = bits345 | wkday
data[4] = tobcd(day)
data[5] = tobcd(month)
if leap:
data[5] |= LPYR
data[6] = tobcd(year % 100)
i2cbus.write_i2c_block_data(RTCADR, 0, data)
def writealm(i2cbus, alm, dt):
if alm > 0:
alm = 1
else:
alm = 0
sec = dt.second
min = dt.minute
hour = dt.hour
# rtc-ds1307 uses weekday convention Sun = 1, Sat = 7
# wkday in alarm has to match the wkday of rtc time for the alarm to trigger
wkday = (dt.weekday() + 1)%7 + 1
day = dt.day
month = dt.month
year = dt.year
data = [0,0,0,0,0,0]
data[0] = tobcd(sec)
data[1] = tobcd(min)
data[2] = tobcd(hour)
data[3] = 0x70 | wkday # ALM0MSK = 111
data[4] = tobcd(day)
data[5] = tobcd(month)
i2cbus.write_i2c_block_data(RTCADR, almbase[alm], data)
def readrtc(i2cbus):
data=i2cbus.read_i2c_block_data(RTCADR, 0, 7)
sec = (data[0] & 0x7f) // 16 * 10 + (data[0] & 0x0f)
min = data[1] // 16 * 10 + (data[1] & 0x0f)
hour = data[2] // 16 * 10 + (data[2] & 0x0f)
day = data[4] // 16 * 10 + (data[4] & 0x0f)
month = (data[5] & 0x10) // 16 * 10 + (data[5] & 0x0f)
year = data[6] // 16 * 10 + (data[6] & 0x0f)
dt = datetime(2000+year, month, day, hour, min, sec)
return dt
def readalm(i2cbus, alm):
if alm > 0:
alm = 1
else:
alm = 0
data = i2cbus.read_i2c_block_data(RTCADR, almbase[alm], 6)
sec = data[0] // 16 * 10 + (data[0] & 0x0f)
min = data[1] // 16 * 10 + (data[1] & 0x0f)
hour = data[2] // 16 * 10 + (data[2] & 0x0f)
day = data[4] // 16 * 10 + (data[4] & 0x0f)
month = data[5] // 16 * 10 + (data[5] & 0x0f)
# year not used in alarm time
dt = datetime(2000, month, day, hour, min, sec)
return dt
def enablealm0(i2cbus):
data = i2cbus.read_byte_data(RTCADR, 7)
data |= 0x10
i2cbus.write_byte_data(RTCADR, 7, data)
def enablealm1(i2cbus):
data = i2cbus.read_byte_data(RTCADR, 7)
data |= 0x20
i2cbus.write_byte_data(RTCADR, 7, data)
def disablealm0(i2cbus):
# When disabling the alarm, keep the mfp output high (otherwise we'll get an immediate reboot)
data = i2cbus.read_byte_data(RTCADR, 7)
data &= 0xef
data |= 0x80
i2cbus.write_byte_data(RTCADR, 7, data)
def disablealm1(i2cbus):
# When disabling the alarm, keep the mfp output high (otherwise we'll get an immediate reboot)
data = i2cbus.read_byte_data(RTCADR, 7)
data &= 0xdf
data |= 0x80
i2cbus.write_byte_data(RTCADR, 7, data)
def enablesqw(i2cbus):
# Set 1 Hz square wave output
i2cbus.write_byte_data(RTCADR, 7, 0x40)
def disablesqw(i2cbus):
# Disable square wave and set ouput high
i2cbus.write_byte_data(RTCADR, 7, 0x80)
def mfpoutput(i2cbus, val):
# set MFP output directly
if val == 0:
data = 0x00
else:
data = 0x80
i2cbus.write_byte_data(RTCADR, 7, data)