blob: 0ae7c014ecdcdfb0a57a050a1a96eab78062f624 (
plain)
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
|
#include "../sensor_dht22.h"
#ifdef CONFIG_IOE_SENSOR_DHT22
#define PP dht22_ports[pi]
#define PPP dht22_ports[dht22_measurement.pi]
#define TIMEOUT F_CPU/40000
#define STATUS_NONE 0
#define STATUS_COMPLETE 1
#define STATUS_TIMEOUT 2
#define PORT_SENSORW 4
#define PORT_SENSORRESP_L 3
#define PORT_SENSORRESP_H 2
#define PORT_H 1
#define PORT_L 0
struct {
uint8_t index;
uint8_t data[5];
volatile uint8_t status;
uint8_t pi;
uint8_t port_status;
} dht22_measurement;
inline void dht22_init(uint8_t pi) {
// Set port as output and set level hight
*(PP.DDR) |= PP.MASK;
*(PP.PORT) |= PP.MASK;
// Enable all pin change interrupts
PCIFR = 0xff;
}
inline void dht22_read_deac(uint8_t status) {
dht22_measurement.status = status;
// Disable pin change interrupt
*(PPP.PCMSK) &= ~PPP.PCMSK_MASK;
timer_disable(CONFIG_IOE_SENSOR_DHT22_TIMER);
}
// This is called from pcint.c
void dht22_read_pcint(void) {
switch (dht22_measurement.port_status) {
case PORT_L:
if (!(*(PPP.PIN) & PPP.MASK))
return;
dht22_measurement.port_status = PORT_H;
break;
case PORT_H:
if (*(PPP.PIN) & PPP.MASK)
return;
dht22_measurement.port_status = PORT_L;
register uint16_t val;
val = timer_value(CONFIG_IOE_SENSOR_DHT22_TIMER);
// TODO compare value
if (val < 1) {
dht22_measurement.data[dht22_measurement.index / 8]
}
if (++(dht22_measurement.index) == 40) {
dht22_read_deac(STATUS_COMPLETE);
return;
}
break;
default:
if (((*(PPP.PIN) & PPP.MASK) && dht22_measurement.port_status == 3) ||
!(*(PPP.PIN & PPP.MASK)))
return;
dht22_measurement.port_status--;
}
timer_reset(CONFIG_IOE_SENSOR_DHT22_TIMER);
}
void dht22_read_timer_overflow(void) {
dht22_read_deac(STATUS_TIMEOUT);
}
int8_t dht22_read(uint8_t pi, struct dht22_value *rh,
struct dht22_value *t) {
dht22_measurement.index = 0;
dht22_measurement.status = STATUS_NONE;
dht22_measurement.pi = pi;
dht22_measurement.port_status = PORT_SENSORW;
// Pull port down for 500us
*(PP.PORT) &= ~PP.MASK;
_delay_us(500);
// Initialize timer
timer_init(CONFIG_IOE_SENSOR_DHT22_TIMER, TIMER_DIVIDER_64);
timer_sethook(CONFIG_IOE_SENSOR_DHT22_TIMER, dht22_read_timer_overflow);
// Set pin change interrupt
*(PP.PCMSK) |= PP.PCMSK_MASK;
// Set port as output and pull-up resistor
*(PP.DDR) &= ~PP.MASK;
*(PP.PORT) |= PP.MASK;
// Delay till reading is done
taskDelayTill(&(dht22_measurement.status));
// Copy data
rh->integral = dht22_measurement.data[0];
rh->decimal = dht22_measurement.data[1];
t->integral = dht22_measurement.data[2];
t->decimal = dht22_measurement.data[3];
// Check sum
uint8_t sum = dht22_measurement.data[0];
sum += dht22_measurement.data[1];
sum += dht22_measurement.data[2];
sum += dht22_measurement.data[3];
if (sum != dht22_measurement.data[4])
return 1;
return dht22_measurement.status - 1;
}
#endif /* CONFIG_IOE_SENSOR_SHT22 */
|