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
use crate::com::i2c;
use crate::delay::delay_ms;
use fixed_slice_vec::FixedSliceVec;
#[repr(C, packed)]
pub struct AHT10<'a> {
address: u8,
i2c: i2c::Twi,
vec: FixedSliceVec<'a, u8>,
}
const AHT10_INIT_CMD: u8 = 0xE1;
const AHT10_START_MEASURMENT_CMD: u8 = 0xAC;
const AHT10_SOFT_RESET_CMD: u8 = 0xBA;
const AHT10_INIT_CAL_ENABLE: u8 = 0x08;
const AHT10_INIT_BUSY: u8 = 0x08;
impl<'a> AHT10<'a> {
pub fn new(&mut self) -> &'static mut Self {
delay_ms(20);
self.soft_reset();
unsafe {
if !self.initialise() {
unreachable!();
}
}
unsafe { &mut *(0x38 as *mut Self) }
}
pub fn get() -> &'static mut Self {
unsafe { &mut *(0x38 as *mut Self) }
}
pub unsafe fn initialise(&mut self) -> bool {
self.vec.clear();
self.vec.push(AHT10_INIT_CMD);
self.vec.push(0x33);
self.vec.push(0x00);
if !self.i2c.write_to_slave(self.address, &self.vec) {
unreachable!();
}
self.wait_for_idle();
if !(self.status() == 0 && AHT10_INIT_CAL_ENABLE == 0) {
return false;
}
return true;
}
pub fn soft_reset(&mut self) {
self.vec.clear();
self.vec.push(AHT10_SOFT_RESET_CMD);
if !self.i2c.write_to_slave(self.address, &self.vec) {
unreachable!()
}
}
pub unsafe fn read_to_buffer(&mut self) {
if !self
.i2c
.read_from_slave(self.address, self.vec.len(), &mut self.vec)
{
unreachable!();
}
}
pub unsafe fn trigger_slave(&mut self) {
self.vec.clear();
self.vec.push(AHT10_START_MEASURMENT_CMD);
self.vec.push(0x33);
self.vec.push(0x00);
if !self.i2c.write_to_slave(self.address, &self.vec) {
unreachable!();
}
}
pub unsafe fn wait_for_idle(&mut self) {
while (self.status() == 0 && AHT10_INIT_BUSY == 0) == true {
delay_ms(5);
}
}
pub unsafe fn perform_measurement(&mut self) {
self.trigger_slave();
self.wait_for_idle();
self.read_to_buffer();
}
pub unsafe fn status(&mut self) -> u8 {
self.read_to_buffer();
return self.vec[0];
}
pub fn relative_humidity(&mut self) -> f64 {
unsafe {
self.perform_measurement();
let mut humid: f64 = (((self.vec[1] as u32) << 12)
| ((self.vec[2] as u32) << 4)
| ((self.vec[3] as u32) >> 4)) as f64;
humid = (humid * 100.0) / 0x100000 as f64;
return humid;
}
}
pub fn temperature(&mut self) -> f64 {
unsafe {
self.perform_measurement();
let mut temp: f64 = ((((self.vec[3] as u32) & 0xF) << 16)
| (self.vec[4] as u32) << 8
| (self.vec[5]) as u32) as f64;
temp = ((temp as f64 * 200.0) / 0x100000 as f64) - 50.0;
return temp;
}
}
}