esp-who/components/modules/led/who_led.c

163 lines
4.8 KiB
C

#include "who_led.h"
static const char *TAG = "app_led";
static QueueHandle_t xQueueLEDControlI = NULL;
static int gpio_led;
#if CONFIG_LED_ILLUMINATOR_ENABLED
#include "esp_log.h"
#include "driver/ledc.h"
#if CONFIG_LED_LEDC_LOW_SPEED_MODE
#define CONFIG_LED_LEDC_SPEED_MODE LEDC_LOW_SPEED_MODE
#else
#define CONFIG_LED_LEDC_SPEED_MODE LEDC_HIGH_SPEED_MODE
#endif
void app_led_init()
{
gpio_set_direction(CONFIG_LED_LEDC_PIN, GPIO_MODE_OUTPUT);
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_8_BIT, // resolution of PWM duty
.freq_hz = 1000, // frequency of PWM signal
.speed_mode = LEDC_LOW_SPEED_MODE, // timer mode
.timer_num = CONFIG_LED_LEDC_TIMER // timer index
};
ledc_channel_config_t ledc_channel = {
.channel = CONFIG_LED_LEDC_CHANNEL,
.duty = 0,
.gpio_num = CONFIG_LED_LEDC_PIN,
.speed_mode = LEDC_LOW_SPEED_MODE,
.hpoint = 0,
.timer_sel = CONFIG_LED_LEDC_TIMER};
#if CONFIG_LED_LEDC_HIGH_SPEED_MODE
ledc_timer.speed_mode = ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
#endif
switch (ledc_timer_config(&ledc_timer))
{
case ESP_ERR_INVALID_ARG:
ESP_LOGE(TAG, "ledc_timer_config() parameter error");
break;
case ESP_FAIL:
ESP_LOGE(TAG, "ledc_timer_config() Can not find a proper pre-divider number base on the given frequency and the current duty_resolution");
break;
case ESP_OK:
if (ledc_channel_config(&ledc_channel) == ESP_ERR_INVALID_ARG)
{
ESP_LOGE(TAG, "ledc_channel_config() parameter error");
}
break;
default:
break;
}
ESP_LOGE(TAG, "LED has been initialized.");
}
void app_led_duty(int duty)
{ // Turn LED On or Off
if (duty > CONFIG_LED_MAX_INTENSITY)
duty = CONFIG_LED_MAX_INTENSITY;
ledc_set_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL, duty);
ledc_update_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL);
ESP_LOGI(TAG, "Set LED intensity to %d", duty);
}
#endif
static void led_task(void *arg)
{
led_state_t led_op;
while (1)
{
xQueueReceive(xQueueLEDControlI, &led_op, portMAX_DELAY);
switch (led_op)
{
case LED_ALWAYS_OFF:
gpio_set_level(gpio_led, 0);
break;
case LED_ALWAYS_ON:
gpio_set_level(gpio_led, 1);
break;
case LED_OFF_1S:
gpio_set_level(gpio_led, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 1);
break;
case LED_OFF_2S:
gpio_set_level(gpio_led, 0);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 1);
break;
case LED_OFF_4S:
gpio_set_level(gpio_led, 0);
vTaskDelay(4000 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 1);
break;
case LED_ON_1S:
gpio_set_level(gpio_led, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 0);
break;
case LED_ON_2S:
gpio_set_level(gpio_led, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 0);
break;
case LED_ON_4S:
gpio_set_level(gpio_led, 1);
vTaskDelay(4000 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 0);
break;
case LED_BLINK_1S:
for (int i = 0; i < 2; ++i)
{
gpio_set_level(gpio_led, 1);
vTaskDelay(250 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 0);
vTaskDelay(250 / portTICK_PERIOD_MS);
}
break;
case LED_BLINK_2S:
for (int i = 0; i < 4; ++i)
{
gpio_set_level(gpio_led, 1);
vTaskDelay(250 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 0);
vTaskDelay(250 / portTICK_PERIOD_MS);
}
break;
case LED_BLINK_4S:
for (int i = 0; i < 8; ++i)
{
gpio_set_level(gpio_led, 1);
vTaskDelay(250 / portTICK_PERIOD_MS);
gpio_set_level(gpio_led, 0);
vTaskDelay(250 / portTICK_PERIOD_MS);
}
break;
default:
break;
}
}
}
void register_led(const gpio_num_t led_io_num, const QueueHandle_t control_i)
{
xQueueLEDControlI = control_i;
gpio_led = led_io_num;
gpio_config_t gpio_conf;
gpio_conf.mode = GPIO_MODE_OUTPUT_OD;
gpio_conf.pull_up_en = 1;
gpio_conf.intr_type = GPIO_INTR_DISABLE;
gpio_conf.pin_bit_mask = 1LL << gpio_led;
gpio_config(&gpio_conf);
xTaskCreatePinnedToCore(&led_task, "who_led_task", 1 * 1024, NULL, 5, NULL, 0);
}