-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathdht22_sm.c
136 lines (108 loc) · 2.76 KB
/
dht22_sm.c
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
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/slab.h>
#include "dht22_sm.h"
static void reset_dht22_sm(struct dht22_sm *sm);
static enum dht22_state get_next_state_idle(struct dht22_sm *sm);
static enum dht22_state get_next_state_responding(struct dht22_sm *sm);
static enum dht22_state get_next_state_finished(struct dht22_sm *sm);
static enum dht22_state get_next_state_error(struct dht22_sm *sm);
static void handle_idle(struct dht22_sm *sm);
static void handle_finished(struct dht22_sm *sm);
static void noop(struct dht22_sm *sm);
static void change_dht22_sm_state(struct dht22_sm *sm);
static void handle_dht22_state(struct dht22_sm *sm);
static enum dht22_state
(*state_functions[COUNT_STATES])(struct dht22_sm *sm) = {
get_next_state_idle,
get_next_state_responding,
get_next_state_finished,
get_next_state_error
};
static void (*handler_functions[COUNT_STATES])(struct dht22_sm *sm) = {
handle_idle,
noop,
handle_finished,
noop
};
static void noop(struct dht22_sm *sm) { }
struct dht22_sm *
create_sm(struct work_struct *work,
struct work_struct *cleanup_work,
struct workqueue_struct *wq)
{
struct dht22_sm *sm;
sm = kmalloc(sizeof(struct dht22_sm), GFP_KERNEL);
if (!sm) {
pr_err("Could not create state machine. Exiting...\n");
return ERR_PTR(-ENOMEM);
}
sm->reset = reset_dht22_sm;
sm->change_state = change_dht22_sm_state;
sm->handle_state = handle_dht22_state;
sm->work = work;
sm->cleanup_work = cleanup_work;
sm->wq = wq;
sm->reset(sm);
return sm;
}
void destroy_sm(struct dht22_sm *sm)
{
kfree(sm);
}
static enum dht22_state get_next_state_idle(struct dht22_sm *sm)
{
if (sm->error)
return ERROR;
if (sm->triggered)
return RESPONDING;
return IDLE;
}
static enum dht22_state get_next_state_responding(struct dht22_sm *sm)
{
if (sm->error)
return ERROR;
if (sm->finished)
return FINISHED;
return RESPONDING;
}
static enum dht22_state get_next_state_finished(struct dht22_sm *sm)
{
if (sm->error)
return ERROR;
return IDLE;
}
static enum dht22_state get_next_state_error(struct dht22_sm *sm)
{
return IDLE;
}
static void handle_idle(struct dht22_sm *sm)
{
if (sm->dirty)
queue_work(sm->wq, sm->cleanup_work);
}
static void handle_finished(struct dht22_sm *sm)
{
queue_work(sm->wq, sm->work);
}
static void change_dht22_sm_state(struct dht22_sm *sm)
{
sm->state = (*state_functions[sm->state])(sm);
}
static void handle_dht22_state(struct dht22_sm *sm)
{
(*handler_functions[sm->state])(sm);
}
static void reset_dht22_sm(struct dht22_sm *sm)
{
sm->state = IDLE;
sm->finished = false;
sm->triggered = false;
sm->error = false;
sm->dirty = false;
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Filip Kolev");
MODULE_DESCRIPTION("A test module for the DHT22 sensor.");
MODULE_VERSION("0.1");