mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-11 22:17:17 +03:00
driver for ST7735/89 & LED PWM
This commit is contained in:
@@ -10,14 +10,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define I2C_SYSTEM_PORT 1
|
||||
#define SPI_SYSTEM_HOST SPI2_HOST
|
||||
#define I2C_SYSTEM_PORT 1
|
||||
#define SPI_SYSTEM_HOST SPI2_HOST
|
||||
|
||||
extern int i2c_system_port;
|
||||
extern int i2c_system_speed;
|
||||
extern int spi_system_host;
|
||||
extern int spi_system_dc_gpio;
|
||||
extern bool gpio36_39_used;
|
||||
typedef struct {
|
||||
int timer, base_channel, max;
|
||||
} pwm_system_t;
|
||||
extern pwm_system_t pwm_system;
|
||||
|
||||
#ifdef CONFIG_SQUEEZEAMP
|
||||
#define ADAC dac_tas57xx
|
||||
|
||||
@@ -10,13 +10,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "led.h"
|
||||
#include "globdefs.h"
|
||||
#include "accessors.h"
|
||||
|
||||
#define MAX_LED 8
|
||||
@@ -29,6 +32,8 @@ static struct led_s {
|
||||
bool on;
|
||||
int onstate;
|
||||
int ontime, offtime;
|
||||
int pwm;
|
||||
int channel;
|
||||
int pushedon, pushedoff;
|
||||
bool pushed;
|
||||
TimerHandle_t timer;
|
||||
@@ -37,8 +42,22 @@ static struct led_s {
|
||||
static struct {
|
||||
int gpio;
|
||||
int active;
|
||||
} green = { CONFIG_LED_GREEN_GPIO, 0 },
|
||||
red = { CONFIG_LED_RED_GPIO, 0 };
|
||||
int pwm;
|
||||
} green = { .gpio = CONFIG_LED_GREEN_GPIO, .active = 0, .pwm = -1 },
|
||||
red = { .gpio = CONFIG_LED_RED_GPIO, .active = 0, .pwm = -1 };
|
||||
|
||||
static int led_max = 2;
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
static void set_level(struct led_s *led, bool on) {
|
||||
if (led->pwm < 0) gpio_set_level(led->gpio, on ? led->onstate : !led->onstate);
|
||||
else {
|
||||
ledc_set_duty(LEDC_HIGH_SPEED_MODE, led->channel, on ? led->pwm : (led->onstate ? 0 : pwm_system.max));
|
||||
ledc_update_duty(LEDC_HIGH_SPEED_MODE, led->channel);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
@@ -49,9 +68,9 @@ static void vCallbackFunction( TimerHandle_t xTimer ) {
|
||||
if (!led->timer) return;
|
||||
|
||||
led->on = !led->on;
|
||||
ESP_LOGD(TAG,"led vCallbackFunction setting gpio %d level", led->gpio);
|
||||
gpio_set_level(led->gpio, led->on ? led->onstate : !led->onstate);
|
||||
|
||||
ESP_EARLY_LOGD(TAG,"led vCallbackFunction setting gpio %d level %d (pwm:%d)", led->gpio, led->on, led->pwm);
|
||||
set_level(led, led->on);
|
||||
|
||||
// was just on for a while
|
||||
if (!led->on && led->offtime == -1) return;
|
||||
|
||||
@@ -63,7 +82,7 @@ static void vCallbackFunction( TimerHandle_t xTimer ) {
|
||||
*
|
||||
*/
|
||||
bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
|
||||
if (!leds[idx].gpio || leds[idx].gpio<0 ) return false;
|
||||
if (!leds[idx].gpio || leds[idx].gpio < 0 ) return false;
|
||||
|
||||
ESP_LOGD(TAG,"led_blink_core");
|
||||
if (leds[idx].timer) {
|
||||
@@ -89,25 +108,40 @@ bool led_blink_core(int idx, int ontime, int offtime, bool pushed) {
|
||||
|
||||
if (ontime == 0) {
|
||||
ESP_LOGD(TAG,"led %d, setting reverse level", idx);
|
||||
gpio_set_level(leds[idx].gpio, !leds[idx].onstate);
|
||||
set_level(leds + idx, false);
|
||||
} else if (offtime == 0) {
|
||||
ESP_LOGD(TAG,"led %d, setting level", idx);
|
||||
gpio_set_level(leds[idx].gpio, leds[idx].onstate);
|
||||
set_level(leds + idx, true);
|
||||
} else {
|
||||
if (!leds[idx].timer) {
|
||||
ESP_LOGD(TAG,"led %d, Creating timer", idx);
|
||||
leds[idx].timer = xTimerCreate("ledTimer", ontime / portTICK_RATE_MS, pdFALSE, (void *)&leds[idx], vCallbackFunction);
|
||||
}
|
||||
leds[idx].on = true;
|
||||
ESP_LOGD(TAG,"led %d, Setting gpio %d", idx, leds[idx].gpio);
|
||||
gpio_set_level(leds[idx].gpio, leds[idx].onstate);
|
||||
ESP_LOGD(TAG,"led %d, Starting timer.", idx);
|
||||
set_level(leds + idx, true);
|
||||
|
||||
ESP_LOGD(TAG,"led %d, Setting gpio %d and starting timer", idx, leds[idx].gpio);
|
||||
if (xTimerStart(leds[idx].timer, BLOCKTIME) == pdFAIL) return false;
|
||||
}
|
||||
ESP_LOGD(TAG,"led %d, led_blink_core_done", idx);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
bool led_brightness(int idx, int pwm) {
|
||||
if (pwm > 100) pwm = 100;
|
||||
leds[idx].pwm = pwm_system.max * powf(pwm / 100.0, 3);
|
||||
if (!leds[idx].onstate) leds[idx].pwm = pwm_system.max - leds[idx].pwm;
|
||||
|
||||
ledc_set_duty(LEDC_HIGH_SPEED_MODE, leds[idx].channel, leds[idx].pwm);
|
||||
ledc_update_duty(LEDC_HIGH_SPEED_MODE, leds[idx].channel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
@@ -123,34 +157,50 @@ bool led_unpush(int idx) {
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
bool led_config(int idx, gpio_num_t gpio, int onstate) {
|
||||
if(gpio<0){
|
||||
ESP_LOGW(TAG,"LED GPIO not configured");
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s", idx, gpio, onstate>0?"On":"Off");
|
||||
if (idx >= MAX_LED) return false;
|
||||
leds[idx].gpio = gpio;
|
||||
leds[idx].onstate = onstate;
|
||||
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s. Selecting GPIO pad", idx, gpio, onstate>0?"On":"Off");
|
||||
gpio_pad_select_gpio(gpio);
|
||||
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s. Setting direction to OUTPUT", idx, gpio, onstate>0?"On":"Off");
|
||||
gpio_set_direction(gpio, GPIO_MODE_OUTPUT);
|
||||
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s. Setting State to %d", idx, gpio, onstate>0?"On":"Off", onstate);
|
||||
gpio_set_level(gpio, !onstate);
|
||||
ESP_LOGD(TAG,"Done configuring the led");
|
||||
return true;
|
||||
int led_allocate(void) {
|
||||
if (led_max < MAX_LED) return led_max++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************************
|
||||
*
|
||||
*/
|
||||
bool led_unconfig(int idx) {
|
||||
if (idx >= MAX_LED) return false;
|
||||
bool led_config(int idx, gpio_num_t gpio, int onstate, int pwm) {
|
||||
if (gpio < 0) {
|
||||
ESP_LOGW(TAG,"LED GPIO not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (leds[idx].timer) xTimerDelete(leds[idx].timer, BLOCKTIME);
|
||||
leds[idx].timer = NULL;
|
||||
ESP_LOGD(TAG,"Index %d, GPIO %d, on state %s", idx, gpio, onstate>0?"On":"Off");
|
||||
if (idx >= MAX_LED) return false;
|
||||
|
||||
leds[idx].gpio = gpio;
|
||||
leds[idx].onstate = onstate;
|
||||
leds[idx].pwm = -1;
|
||||
|
||||
if (pwm < 0) {
|
||||
gpio_pad_select_gpio(gpio);
|
||||
gpio_set_direction(gpio, GPIO_MODE_OUTPUT);
|
||||
} else {
|
||||
leds[idx].channel = pwm_system.base_channel++;
|
||||
leds[idx].pwm = pwm_system.max * powf(pwm / 100.0, 3);
|
||||
if (!onstate) leds[idx].pwm = pwm_system.max - leds[idx].pwm;
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.channel = leds[idx].channel,
|
||||
.duty = leds[idx].pwm,
|
||||
.gpio_num = gpio,
|
||||
.speed_mode = LEDC_HIGH_SPEED_MODE,
|
||||
.hpoint = 0,
|
||||
.timer_sel = pwm_system.timer,
|
||||
};
|
||||
|
||||
ledc_channel_config(&ledc_channel);
|
||||
}
|
||||
|
||||
set_level(leds + idx, false);
|
||||
ESP_LOGD(TAG,"PWM Index %d, GPIO %d, on state %s, pwm %d%%", idx, gpio, onstate > 0 ? "On" : "Off", pwm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -170,7 +220,6 @@ void set_led_gpio(int gpio, char *value) {
|
||||
}
|
||||
|
||||
void led_svc_init(void) {
|
||||
|
||||
#ifdef CONFIG_LED_GREEN_GPIO_LEVEL
|
||||
green.active = CONFIG_LED_GREEN_GPIO_LEVEL;
|
||||
#endif
|
||||
@@ -181,8 +230,15 @@ void led_svc_init(void) {
|
||||
#ifndef CONFIG_LED_LOCKED
|
||||
parse_set_GPIO(set_led_gpio);
|
||||
#endif
|
||||
ESP_LOGI(TAG,"Configuring LEDs green:%d (active:%d), red:%d (active:%d)", green.gpio, green.active, red.gpio, red.active);
|
||||
ESP_LOGI(TAG,"Configuring LEDs green:%d (active:%d %d%%), red:%d (active:%d %d%%)", green.gpio, green.active, green.pwm, red.gpio, red.active, red.pwm);
|
||||
|
||||
char *nvs_item = config_alloc_get(NVS_TYPE_STR, "led_brightness"), *p;
|
||||
if (nvs_item) {
|
||||
if ((p = strcasestr(nvs_item, "green")) != NULL) green.pwm = atoi(strchr(p, '=') + 1);
|
||||
if ((p = strcasestr(nvs_item, "red")) != NULL) red.pwm = atoi(strchr(p, '=') + 1);
|
||||
free(nvs_item);
|
||||
}
|
||||
|
||||
led_config(LED_GREEN, green.gpio, green.active);
|
||||
led_config(LED_RED, red.gpio, red.active);
|
||||
led_config(LED_GREEN, green.gpio, green.active, green.pwm);
|
||||
led_config(LED_RED, red.gpio, red.active, red.pwm);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,10 @@ enum { LED_GREEN = 0, LED_RED };
|
||||
#define led_blink(idx, on, off) led_blink_core(idx, on, off, false)
|
||||
#define led_blink_pushed(idx, on, off) led_blink_core(idx, on, off, true)
|
||||
|
||||
bool led_config(int idx, gpio_num_t gpio, int onstate);
|
||||
bool led_unconfig(int idx);
|
||||
bool led_config(int idx, gpio_num_t gpio, int onstate, int pwm);
|
||||
bool led_brightness(int idx, int percent);
|
||||
bool led_blink_core(int idx, int ontime, int offtime, bool push);
|
||||
bool led_unpush(int idx);
|
||||
int led_allocate(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include <driver/i2c.h>
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "platform_config.h"
|
||||
#include "battery.h"
|
||||
#include "led.h"
|
||||
@@ -26,6 +27,11 @@ int i2c_system_port = I2C_SYSTEM_PORT;
|
||||
int i2c_system_speed = 400000;
|
||||
int spi_system_host = SPI_SYSTEM_HOST;
|
||||
int spi_system_dc_gpio = -1;
|
||||
pwm_system_t pwm_system = {
|
||||
.timer = LEDC_TIMER_0,
|
||||
.base_channel = LEDC_CHANNEL_0,
|
||||
.max = (1 << LEDC_TIMER_13_BIT),
|
||||
};
|
||||
|
||||
static const char *TAG = "services";
|
||||
|
||||
@@ -93,6 +99,16 @@ void services_init(void) {
|
||||
spi_system_host = -1;
|
||||
ESP_LOGW(TAG, "no SPI configured");
|
||||
}
|
||||
|
||||
// system-wide PWM timer configuration
|
||||
ledc_timer_config_t pwm_timer = {
|
||||
.duty_resolution = LEDC_TIMER_13_BIT,
|
||||
.freq_hz = 5000,
|
||||
.speed_mode = LEDC_HIGH_SPEED_MODE,
|
||||
.timer_num = pwm_system.timer,
|
||||
};
|
||||
|
||||
ledc_timer_config(&pwm_timer);
|
||||
|
||||
led_svc_init();
|
||||
battery_svc_init();
|
||||
|
||||
Reference in New Issue
Block a user