1. add ISR handler apis so that users of different layers can hook their own isr handler on different GPIO. Audio project has different software layers, they need different gpio isr handler for layer instead of processing all GPIO interrupts in one handler. If this kind of calling a handler from isr is not proper, please kindly point out. 2. add gpio example code. 3. improve gpio.rst 4. add readme for gpio example Squashed commits: [278e50f] update: GPIO 1. coding style, add a space between conditional or loop keyword and an opening paren. 2. modify some return value and doc 3. use printf in example code Squashed commits: [efb23bb] minor change of comment
114 lines
3.4 KiB
C
114 lines
3.4 KiB
C
/* GPIO Example
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "driver/gpio.h"
|
|
|
|
/**
|
|
* Brief:
|
|
* This test code shows how to configure gpio and how to use gpio interrupt.
|
|
*
|
|
* GPIO status:
|
|
* GPIO18: output
|
|
* GPIO19: output
|
|
* GPIO4: input, pulled up, interrupt from rising edge and falling edge
|
|
* GPIO5: input, pulled up, interrupt from rising edge.
|
|
*
|
|
* Test:
|
|
* Connect GPIO18 with GPIO4
|
|
* Connect GPIO19 with GPIO5
|
|
* Generate pulses on GPIO18/19, that triggers interrupt on GPIO4/5
|
|
*
|
|
*/
|
|
|
|
#define GPIO_OUTPUT_IO_0 18
|
|
#define GPIO_OUTPUT_IO_1 19
|
|
#define GPIO_OUTPUT_PIN_SEL ((1<<GPIO_OUTPUT_IO_0) | (1<<GPIO_OUTPUT_IO_1))
|
|
#define GPIO_INPUT_IO_0 4
|
|
#define GPIO_INPUT_IO_1 5
|
|
#define GPIO_INPUT_PIN_SEL ((1<<GPIO_INPUT_IO_0) | (1<<GPIO_INPUT_IO_1))
|
|
#define ESP_INTR_FLAG_DEFAULT 0
|
|
|
|
static xQueueHandle gpio_evt_queue = NULL;
|
|
|
|
void IRAM_ATTR gpio_isr_handler(void* arg)
|
|
{
|
|
uint32_t gpio_num = (uint32_t) arg;
|
|
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
|
|
}
|
|
|
|
void gpio_task_example(void* arg)
|
|
{
|
|
uint32_t io_num;
|
|
for(;;) {
|
|
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
|
|
printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
|
|
}
|
|
}
|
|
}
|
|
|
|
void app_main()
|
|
{
|
|
gpio_config_t io_conf;
|
|
//disable interrupt
|
|
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
|
|
//set as output mode
|
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
|
//bit mask of the pins that you want to set,e.g.GPIO18/19
|
|
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
|
|
//disable pull-down mode
|
|
io_conf.pull_down_en = 0;
|
|
//disable pull-up mode
|
|
io_conf.pull_up_en = 0;
|
|
//configure GPIO with the given settings
|
|
gpio_config(&io_conf);
|
|
|
|
//interrupt of rising edge
|
|
io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
|
|
//bit mask of the pins, use GPIO4/5 here
|
|
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
|
|
//set as input mode
|
|
io_conf.mode = GPIO_MODE_INPUT;
|
|
//enable pull-up mode
|
|
io_conf.pull_up_en = 1;
|
|
gpio_config(&io_conf);
|
|
|
|
//change gpio intrrupt type for one pin
|
|
gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);
|
|
|
|
//create a queue to handle gpio event from isr
|
|
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
|
|
//start gpio task
|
|
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
|
|
|
|
//install gpio isr service
|
|
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
|
|
//hook isr handler for specific gpio pin
|
|
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
|
|
//hook isr handler for specific gpio pin
|
|
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);
|
|
|
|
//remove isr handler for gpio number.
|
|
gpio_isr_handler_remove(GPIO_INPUT_IO_0);
|
|
//hook isr handler for specific gpio pin again
|
|
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
|
|
|
|
int cnt = 0;
|
|
while(1) {
|
|
printf("cnt: %d\n", cnt++);
|
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
|
gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2);
|
|
gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2);
|
|
}
|
|
}
|
|
|