forked from hmbar/epd-embedded-web
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathesp32-2.html
308 lines (268 loc) · 15.1 KB
/
esp32-2.html
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>ERNI Performance Day - Embedded</title>
<!-- Bootstrap core CSS -->
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="css/modern-business.css" rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="index.html">EPD - Embedded</a>
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="about.html">About</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownPortfolio" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Information
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownPortfolio">
<a class="dropdown-item" href="info-rpi.html">Raspberry Pi</a>
<a class="dropdown-item" href="info-esp32.html">ESP32</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link active dropdown-toggle" href="#" id="navbarDropdownPortfolio" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Roadmap
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownPortfolio">
<a class="dropdown-item" href="roadmap-rpi.html">Raspberry Pi</a>
<a class="dropdown-item" href="roadmap-esp32.html">ESP32</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="feedback.html">Feedback</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Page Content -->
<div class="container mb-3">
<ol class="breadcrumb mt-4 mb-3">
<li class="breadcrumb-item">
<a href="index.html">Home</a>
</li>
<li class="breadcrumb-item">
<a href="roadmap-esp32.html">Roadmap ESP32</a>
</li>
<li class="breadcrumb-item active">Project Two</li>
</ol>
<!-- Page Heading/Breadcrumbs -->
<h1 class="mt-4 mb-3">ESP32 Project Two
<br>
<small>Manage GPIOs</small>
</h1>
<hr>
<h3 class="mb-3">Overview</h3>
ESP32 chip has 40 GPIOs, but not all of them are available.
Starting form <code>GPIO_NUM_0</code>, pins 20,24,28-31 are unavailable.
<br>
Other restrictions apply:
<ol>
<li><code>GPIO_NUM_34</code> to <code>GPIO_NUM_39</code> can only be set as input mode and do not have software pullup or pulldown</li>
<li><code>GPIO_NUM_6</code> to <code>GPIO_NUM_11</code> are usually used for SPI flash</li>
</ol>
In order to manage GPIOs the following guidelines should be followed
<ol>
<li>Include the following headers
<ul>
<li>freertos/FreeRTOS.h</li>
<li>driver/gpio.h</li>
</ul>
</li>
<li>Configure the pin using the <a href="esp-idf/docs/api-reference/peripherals/gpio.html" target="_blank">GPIO API</a>.
<br>
It is possible to configure the pin using the <code>gpio_config</code> routine and passing a pointer to a <code>gpio_config_t</code> struct
<br>
<pre><code>
typedef enum {
GPIO_INTR_DISABLE, /*!< Disable GPIO interrupt */
GPIO_INTR_POSEDGE, /*!< GPIO interrupt type : rising edge */
GPIO_INTR_NEGEDGE, /*!< GPIO interrupt type : falling edge */
GPIO_INTR_ANYEDGE, /*!< GPIO interrupt type : both rising and falling edge */
GPIO_INTR_LOW_LEVEL, /*!< GPIO interrupt type : input low level trigger */
GPIO_INTR_HIGH_LEVEL, /*!< GPIO interrupt type : input high level trigger */
GPIO_INTR_MAX,
} gpio_int_type_t;
typedef enum {
GPIO_MODE_INPUT, /*!< GPIO mode : input only */
GPIO_MODE_OUTPUT, /*!< GPIO mode : output only mode */
GPIO_MODE_OUTPUT_OD, /*!< GPIO mode : output only with open-drain mode */
GPIO_MODE_INPUT_OUTPUT_OD, /*!< GPIO mode : output and input with open-drain mode*/
GPIO_MODE_INPUT_OUTPUT, /*!< GPIO mode : output and input mode */
} gpio_mode_t;
typedef enum {
GPIO_PULLUP_DISABLE, /*!< Disable GPIO pull-up resistor */
GPIO_PULLUP_ENABLE, /*!< Enable GPIO pull-up resistor */
} gpio_pullup_t;
typedef enum {
GPIO_PULLDOWN_DISABLE, /*!< Disable GPIO pull-down resistor */
GPIO_PULLDOWN_ENABLE, /*!< Enable GPIO pull-down resistor */
} gpio_pulldown_t;
/**
* @brief Configuration parameters of GPIO pad for gpio_config function
*/
typedef struct {
uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
gpio_mode_t mode; /*!< GPIO mode: set input/output mode */
gpio_pullup_t pull_up_en; /*!< GPIO pull-up */
gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */
gpio_int_type_t intr_type; /*!< GPIO interrupt type */
} gpio_config_t;
esp_err_t gpio_config(const gpio_config_t *pGPIOConfig);
</code></pre>
or using the following routines to configure a pin individually
<pre><code>
typedef enum {
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
GPIO_NUM_2 = 2, /*!< GPIO2, input and output */
GPIO_NUM_3 = 3, /*!< GPIO3, input and output */
GPIO_NUM_4 = 4, /*!< GPIO4, input and output */
GPIO_NUM_5 = 5, /*!< GPIO5, input and output */
GPIO_NUM_6 = 6, /*!< GPIO6, input and output */
GPIO_NUM_7 = 7, /*!< GPIO7, input and output */
GPIO_NUM_8 = 8, /*!< GPIO8, input and output */
GPIO_NUM_9 = 9, /*!< GPIO9, input and output */
GPIO_NUM_10 = 10, /*!< GPIO10, input and output */
GPIO_NUM_11 = 11, /*!< GPIO11, input and output */
GPIO_NUM_12 = 12, /*!< GPIO12, input and output */
GPIO_NUM_13 = 13, /*!< GPIO13, input and output */
GPIO_NUM_14 = 14, /*!< GPIO14, input and output */
GPIO_NUM_15 = 15, /*!< GPIO15, input and output */
GPIO_NUM_16 = 16, /*!< GPIO16, input and output */
GPIO_NUM_17 = 17, /*!< GPIO17, input and output */
GPIO_NUM_18 = 18, /*!< GPIO18, input and output */
GPIO_NUM_19 = 19, /*!< GPIO19, input and output */
GPIO_NUM_21 = 21, /*!< GPIO21, input and output */
GPIO_NUM_22 = 22, /*!< GPIO22, input and output */
GPIO_NUM_23 = 23, /*!< GPIO23, input and output */
GPIO_NUM_25 = 25, /*!< GPIO25, input and output */
GPIO_NUM_26 = 26, /*!< GPIO26, input and output */
GPIO_NUM_27 = 27, /*!< GPIO27, input and output */
GPIO_NUM_32 = 32, /*!< GPIO32, input and output */
GPIO_NUM_33 = 33, /*!< GPIO33, input and output */
GPIO_NUM_34 = 34, /*!< GPIO34, input mode only */
GPIO_NUM_35 = 35, /*!< GPIO35, input mode only */
GPIO_NUM_36 = 36, /*!< GPIO36, input mode only */
GPIO_NUM_37 = 37, /*!< GPIO37, input mode only */
GPIO_NUM_38 = 38, /*!< GPIO38, input mode only */
GPIO_NUM_39 = 39, /*!< GPIO39, input mode only */
GPIO_NUM_MAX = 40,
} gpio_num_t;
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
typedef enum {
GPIO_PULLUP_ONLY, /*!< Pad pull up */
GPIO_PULLDOWN_ONLY, /*!< Pad pull down */
GPIO_PULLUP_PULLDOWN, /*!< Pad pull up + pull down*/
GPIO_FLOATING, /*!< Pad floating */
} gpio_pull_mode_t;
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
esp_err_t gpio_pullup_en(gpio_num_t gpio_num);
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num);
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
</code></pre>
</li>
<li>
Use the GPIOs using the following routines
<pre><code>
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
int gpio_get_level(gpio_num_t gpio_num);
</code></pre>
</li>
</ol>
<hr>
<p>
In order to handle the inputs by interruption, we will need to install an ISR routine.
<br>
In addition, it is a good practice to leave the ISR as light as possible,
just signaling/enqueuing the events there, and leaving the process to another task.
<br>
Sometimes the task that processes those events may be different from the main task.
</p>
<p>
For that you should:
<br>
<ol>
<li>Create a ISR routine following this signature <code>static void IRAM_ATTR my_isr_handler(void* arg)</code></li>
<li>Include the header <code>freertos/semphr.h</code> to be able to use semaphores</li>
<li>Create a semaphore to signal the worker process using the routine <code>xSemaphoreCreateBinary</code>. See <a href="freertos/xSemaphoreCreateBinary.html" target="_blank">xSemaphoreCreateBinary documentation</a> for more information</li>
<li>Use the <code>xSemaphoreGiveFromISR</code> routine to signal the event from the ISR. See <a href="freertos/a00124.html" target="_blank">xSemaphoreGiveFromISR documentation</a> for more information</li>
<li>Use the <code>xSemaphoreTake</code> routine to receive the signal. See <a href="freertos/a00122.html" target="_blank">xSemaphoreTake documentation</a> for more information</li>
<li>Create a second task using the routine <code>xTaskCreate</code>. See <a href="freertos/a00125.html" target="_blank">xTaskCreate documentation</a> for more information</li>
</ol>
</p>
<hr>
<h3 class="mb-3">Step 1<br><small>Using GPIO as an output</small></h3>
<ol>
<li>Change directory to <code>~/esp/</code></li>
<li>Clone the skeleton project using the command <code>git clone <a href="http://server:8081/PerformanceIOT/esp-skeleton">http://server:8081/PerformanceIOT/esp-skeleton</a> esp-gpio</code></li>
<li>Edit the main.c file
<ul>
<li>Include the appropriate headers</li>
<li>Configure the GPIOs</li>
<li>Toggle an output inside a loop</li>
</ul>
</li>
</ol>
<div class="alert alert-info">If you need help, take a look at <a href="http://server:8081/PerformanceIOT/esp-gpio/tags/1">http://server:8081/PerformanceIOT/esp-gpio/tags/1</a></div>
<div class="alert alert-info">After it works, change your code and try to configure an input-only pin as an output, to check error handling</div>
<hr>
<h3 class="mb-3">Step 2<br><small>Using GPIO as an input</small></h3>
<p>
Modify your code to begin with the led blinking, but after your first event in the input, the led must follow the input. Then, modify it again, to let the led switch after a push-release cycle.
<br>
In the first one, we are turning on/off a light using a regular light button, and in the second one you are using a push-button.
</p>
<ol>
<li>Configure a pin as an input. This pin must have a pull-up or pull-down, internal or external.</li>
<li>Be aware that the loop delay should be short enough, to avoid loosing too many events.</li>
</ol>
<div class="alert alert-info">If you need help, take a look at <a href="http://server:8081/PerformanceIOT/esp-gpio/tags/2">http://server:8081/PerformanceIOT/esp-gpio/tags/2</a></div>
<hr>
<h3 class="mb-3">Step 3<br><small>Manage the inputs in an interrupt-driven way</small></h3>
<p>
Modify your code to have the same behavior, but working in an interrupt-driven way.
</p>
<ol>
<li>Configure the pin to use interrupts.</li>
<li>Add a semaphore to signal the events.</li>
<li>Install an ISR associated with the input pin, and signal the input event.</li>
<li>Add a Task, wait for the semaphore, and process the event.</li>
</ol>
<div class="alert alert-info">If you need help, take a look at <a href="http://server:8081/PerformanceIOT/esp-gpio/tags/3">http://server:8081/PerformanceIOT/esp-gpio/tags/3</a></div>
<hr>
<div class="alert alert-success">
You should be able to handle digital inputs and outputs. If so, congrats!
</div>
</div>
<!-- /.container -->
<!-- Footer -->
<footer class="py-5 bg-dark">
<div class="container">
<p class="m-0 text-center text-white">ERNI Spain - Embedded Firmware Community</p>
</div>
<!-- /.container -->
</footer>
<!-- Bootstrap core JavaScript -->
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/popper/popper.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>