feat: porting to component migrating from esp-idf 4.4 to 5.x

This commit is contained in:
Pietro Marchini
2023-11-19 13:56:03 +01:00
parent d358dcdbda
commit e29bb3d397
19 changed files with 14 additions and 956 deletions

View File

@@ -1,13 +1,14 @@
# ESP32IDFDimmer
# ESP32 Triac Dimmer Driver
This library provides an API to control dimmer devices using the ESP32IDF. It supports both toggle and normal modes, and allows you to set the power levels of the dimmer.
This library provides an API to control dimmer devices using ESP-IDF 5.x.
It supports both toggle and normal modes, and allows you to set the power levels of the dimmer.
### Prerequisites
- ESP32 board with ESP-IDF v4.1 or higher
- ESP32 board with ESP-IDF v5.0 or higher
- A dimmable AC load
### Installation
Clone the project from the repository and add the library to your project.
Clone the component into your project components directory.
### Usage
1. Include the library header in your program
@@ -61,6 +62,14 @@ The library provides the following API methods:
![image](https://user-images.githubusercontent.com/49943249/194775053-0badd3f8-0c23-4a86-8843-abe2f994f5b3.png)
## Migrated to ESP-IDF 5.x and Component
This library has been migrated to ESP-IDF 5.x and is no longer compatible with previous versions.
It has also been transformed into an ESP-IDF component for easier integration.
To use the basic example, add the component to your project's components directory and replace the main file with the code from examples/base/main.c.
If you are using the library in a project that is not using ESP-IDF 5.x, you can still use the old version of the library (v1.0.0) which is compatible with ESP-IDF 4.x.
## Contributing
We welcome contributions to this library. Please open a pull request or an issue to get started.

View File

@@ -1,57 +0,0 @@
#include "esp32idfDimmer.h"
#include "esp_log.h"
#include "esp_err.h"
static const char *TAG = "dimmer_demo";
// Dimmer pointer
dimmertyp *ptr_dimmer;
dimmertyp *ptr_dimmer_2;
volatile bool _init_done;
bool flag;
#define INIT_NOT_DONE _init_done == false
#define _50Hz 50
#define ZEROCROSS_GPIO GPIO_NUM_21
#define TRIAC_1_GPIO GPIO_NUM_22
#define TRIAC_2_GPIO GPIO_NUM_26
#define DIAGNOSTIC_LED_GPIO GPIO_NUM_17
void init();
void app_main()
{
if (INIT_NOT_DONE)
{
init();
// Initial point;
setPower(ptr_dimmer, 1);
}
while (1)
{
// change the output power
getPower(ptr_dimmer) < 60 ? setPower(ptr_dimmer, (getPower(ptr_dimmer) + 5)) : setPower(ptr_dimmer, 1);
setPower(ptr_dimmer_2, getPower(ptr_dimmer));
// wait
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void init()
{
ESP_LOGI(TAG, "Starting init sequence");
// Set diagnostic leds
gpio_set_direction(DIAGNOSTIC_LED_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(DIAGNOSTIC_LED_GPIO, 1);
// Instantiate the new dimmer
ptr_dimmer = createDimmer(TRIAC_1_GPIO, ZEROCROSS_GPIO);
ptr_dimmer_2 = createDimmer(TRIAC_2_GPIO, ZEROCROSS_GPIO);
// startup
begin(ptr_dimmer, NORMAL_MODE, ON, _50Hz);
begin(ptr_dimmer_2, NORMAL_MODE, ON, _50Hz);
ESP_LOGI(TAG, "Init sequence completed");
}

View File

@@ -1,48 +0,0 @@
FROM espressif/idf
ARG DEBIAN_FRONTEND=nointeractive
ARG CONTAINER_USER=esp
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN apt-get update \
&& apt install -y -q \
cmake \
git \
hwdata \
libglib2.0-0 \
libnuma1 \
libpixman-1-0 \
linux-tools-virtual \
&& rm -rf /var/lib/apt/lists/*
RUN update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20
# QEMU
ENV QEMU_REL=esp-develop-20220919
ENV QEMU_SHA256=f6565d3f0d1e463a63a7f81aec94cce62df662bd42fc7606de4b4418ed55f870
ENV QEMU_DIST=qemu-${QEMU_REL}.tar.bz2
ENV QEMU_URL=https://github.com/espressif/qemu/releases/download/${QEMU_REL}/${QEMU_DIST}
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
RUN wget --no-verbose ${QEMU_URL} \
&& echo "${QEMU_SHA256} *${QEMU_DIST}" | sha256sum --check --strict - \
&& tar -xf $QEMU_DIST -C /opt \
&& rm ${QEMU_DIST}
ENV PATH=/opt/qemu/bin:${PATH}
RUN groupadd --gid $USER_GID $CONTAINER_USER \
&& adduser --uid $USER_UID --gid $USER_GID --disabled-password --gecos "" ${CONTAINER_USER} \
&& usermod -a -G dialout $CONTAINER_USER
USER ${CONTAINER_USER}
ENV USER=${CONTAINER_USER}
WORKDIR /home/${CONTAINER_USER}
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
CMD ["/bin/bash", "-c"]

View File

@@ -1,47 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/ubuntu
{
"name": "ESP-IDF QEMU",
"build": {
"dockerfile": "Dockerfile"
},
// Add the IDs of extensions you want installed when the container is created
"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind",
/* the path of workspace folder to be opened after container is running
*/
"workspaceFolder": "${localWorkspaceFolder}",
"mounts": [
"source=extensionCache,target=/root/.vscode-server/extensions,type=volume"
],
"customizations": {
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.1_py3.8_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"extensions": [
"ms-vscode.cpptools",
"espressif.esp-idf-extension"
],
},
"codespaces": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.1_py3.8_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"extensions": [
"ms-vscode.cpptools",
"espressif.esp-idf-extension"
],
}
},
"runArgs": ["--privileged"]
}

View File

@@ -1,3 +0,0 @@
build/
sdkconfig
sdkconfig.old

View File

@@ -1,26 +0,0 @@
{
"configurations": [
{
"name": "ESP-IDF",
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp32-elf/esp-12.2.0_20230208/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc",
"includePath": [
"${config:idf.espIdfPath}/components/**",
"${config:idf.espIdfPathWin}/components/**",
"${config:idf.espAdfPath}/components/**",
"${config:idf.espAdfPathWin}/components/**",
"${workspaceFolder}/**"
],
"browse": {
"path": [
"${config:idf.espIdfPath}/components",
"${config:idf.espIdfPathWin}/components",
"${config:idf.espAdfPath}/components/**",
"${config:idf.espAdfPathWin}/components/**",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": false
}
}
],
"version": 4
}

View File

@@ -1,10 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "espidf",
"name": "Launch",
"request": "launch"
}
]
}

View File

@@ -1,10 +0,0 @@
{
"C_Cpp.intelliSenseEngine": "default",
"files.associations": {
"esp32-triac-dimmer-driver.h": "c",
"gpio.h": "c",
"stdlib.h": "c"
},
"idf.port": "/dev/cu.usbserial-0001",
"idf.flashType": "UART"
}

View File

@@ -1,258 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build - Build project",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py build",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py build",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"autoDetect",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Set ESP-IDF Target",
"type": "shell",
"command": "${command:espIdf.setTarget}",
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"autoDetect",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "Clean - Clean the project",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py fullclean",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py fullclean",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"autoDetect",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
]
},
{
"label": "Flash - Flash the device",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} -b ${config:idf.flashBaudRate} flash",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py flash -p ${config:idf.portWin} -b ${config:idf.flashBaudRate}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"autoDetect",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
]
},
{
"label": "Monitor: Start the monitor",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} monitor",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py -p ${config:idf.portWin} monitor",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"autoDetect",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
],
"dependsOn": "Flash - Flash the device"
},
{
"label": "OpenOCD: Start openOCD",
"type": "shell",
"presentation": {
"echo": true,
"reveal": "never",
"focus": false,
"panel": "new"
},
"command": "openocd -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
"windows": {
"command": "openocd.exe -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"autoDetect",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "adapter",
"type": "shell",
"command": "${config:idf.pythonBinPath}",
"isBackground": true,
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}",
"PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter"
}
},
"problemMatcher": {
"background": {
"beginsPattern": "\bDEBUG_ADAPTER_STARTED\b",
"endsPattern": "DEBUG_ADAPTER_READY2CONNECT",
"activeOnStart": true
},
"pattern": {
"regexp": "(\\d+)-(\\d+)-(\\d+)\\s(\\d+):(\\d+):(\\d+),(\\d+)\\s-(.+)\\s(ERROR)",
"file": 8,
"line": 2,
"column": 3,
"severity": 4,
"message": 9
}
},
"args": [
"${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter_main.py",
"-e",
"${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
"-s",
"${command:espIdf.getOpenOcdScriptValue}",
"-ip",
"localhost",
"-dn",
"${config:idf.adapterTargetName}",
"-om",
"connect_to_instance"
],
"windows": {
"command": "${config:idf.pythonBinPathWin}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}",
"PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter"
}
}
}
}
]
}

View File

@@ -1,8 +0,0 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(template-app)

View File

@@ -1,32 +0,0 @@
# _Sample project_
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This is the simplest buildable example. The example is used by command `idf.py create-project`
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project)
## How to use example
We encourage the users to use the example as a template for the new projects.
A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project).
## Example folder contents
The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main).
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt`
files that provide set of directives and instructions describing the project's source files and targets
(executable, library, or both).
Below is short explanation of remaining files in the project folder.
```
├── CMakeLists.txt
├── main
│   ├── CMakeLists.txt
│   └── main.c
└── README.md This is the file you are currently reading
```
Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system.
They are not used or needed when building with CMake and idf.py.

View File

@@ -1,2 +0,0 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -1,363 +0,0 @@
#include "esp32idfDimmer.h"
static const char *TAG = "Esp32idfDimmer";
int pulseWidth = 2;
volatile int current_dim = 0;
int all_dim = 3;
int rise_fall = true;
char user_zero_cross = '0';
int debug_signal_zc = 0;
bool flagDebug = false;
static int toggleCounter = 0;
static int toggleReload = 25;
volatile bool _initDone = false;
volatile int _steps = 0;
static dimmertyp *dimmer[ALL_DIMMERS];
volatile bool firstSetup = false;
volatile uint16_t dimPower[ALL_DIMMERS];
volatile gpio_num_t dimOutPin[ALL_DIMMERS];
volatile gpio_num_t dimZCPin[ALL_DIMMERS];
volatile uint16_t zeroCross[ALL_DIMMERS];
volatile DIMMER_MODE_typedef dimMode[ALL_DIMMERS];
volatile ON_OFF_typedef dimState[ALL_DIMMERS];
volatile uint16_t dimCounter[ALL_DIMMERS];
static uint16_t dimPulseBegin[ALL_DIMMERS];
volatile uint16_t togMax[ALL_DIMMERS];
volatile uint16_t togMin[ALL_DIMMERS];
volatile bool togDir[ALL_DIMMERS];
/* timer configurations */
timer_config_t m_timer_config;
dimmertyp *createDimmer(gpio_num_t user_dimmer_pin, gpio_num_t zc_dimmer_pin)
{
if (current_dim >= ALL_DIMMERS)
{
return NULL;
}
current_dim++;
dimmer[current_dim - 1] = malloc(sizeof(dimmertyp));
dimmer[current_dim - 1]->current_num = current_dim - 1;
dimmer[current_dim - 1]->toggle_state = false;
dimPulseBegin[current_dim - 1] = 1;
dimOutPin[current_dim - 1] = user_dimmer_pin;
dimZCPin[current_dim - 1] = zc_dimmer_pin;
dimCounter[current_dim - 1] = 0;
zeroCross[current_dim - 1] = 0;
dimMode[current_dim - 1] = NORMAL_MODE;
togMin[current_dim - 1] = 0;
togMax[current_dim - 1] = 1;
// Return the pointer
return dimmer[current_dim - 1];
}
#define TIMER_DIVIDER 80 // Hardware timer clock divider
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
void config_timer(int ACfreq)
{
ESP_LOGI(TAG, "Timer configuration - start");
/*System timer startup has been done*/
if (_initDone)
{
ESP_LOGW(TAG, "Timer configuration - timer already configured");
return;
}
memset(&m_timer_config, 0, sizeof(m_timer_config));
/* Prepare configuration */
timer_config_t m_timer_config =
{
.alarm_en = TIMER_ALARM_DIS,
.counter_en = TIMER_PAUSE,
.counter_dir = TIMER_COUNT_UP,
.auto_reload = TIMER_AUTORELOAD_EN,
.divider = TIMER_DIVIDER,
};
/*self regulation 50/60 Hz*/
double m_calculated_interval = (1 / (double)(ACfreq * 2)) / 100;
ESP_LOGI(TAG, "Interval between wave calculated for frequency : %3dHz = %5f", ACfreq, m_calculated_interval);
ESP_LOGI(TAG, "Timer configuration - configure interrupt and timer");
/* Configure the alarm value and the interrupt on alarm. */
timer_init(TIMER_GROUP_0, TIMER_0, &m_timer_config);
timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_SCALE * m_calculated_interval);
timer_enable_intr(TIMER_GROUP_0, TIMER_0);
timer_isr_register(TIMER_GROUP_0, TIMER_0, onTimerISR, (void *)TIMER_0, ESP_INTR_FLAG_IRAM, NULL);
/* start timer */
ESP_LOGI(TAG, "Timer configuration - start timer");
timer_start(TIMER_GROUP_0, TIMER_0);
timer_set_alarm(TIMER_GROUP_0, TIMER_0, TIMER_ALARM_EN);
ESP_LOGI(TAG, "Timer configuration - completed");
}
/*Zero-crossing pin setting
*set as input
*set as pullup
*set its interrupt*/
void ext_int_init(dimmertyp *ptr)
{
ESP_LOGI(TAG, "Setting ZCPin : %3d as input", dimZCPin[ptr->current_num]);
ESP_LOGI(TAG, "Checking for previous declaration of zc input on the same gpio");
/*Zero crossing*/
bool alreadyInit = false;
for (int i = 0; i < ptr->current_num; i++)
{
if (dimZCPin[i] == dimZCPin[ptr->current_num])
{
alreadyInit = true;
}
}
ESP_LOGI(TAG, "Already init = %3d", alreadyInit);
if (!alreadyInit)
{
gpio_set_direction(dimZCPin[ptr->current_num], GPIO_MODE_INPUT);
gpio_set_intr_type(dimZCPin[ptr->current_num], GPIO_INTR_NEGEDGE);
gpio_intr_enable(dimZCPin[ptr->current_num]);
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
gpio_isr_handler_add(dimZCPin[ptr->current_num], isr_ext, (void *)dimZCPin[ptr->current_num]);
}
ESP_LOGI(TAG, "Zero Cross interrupt configuration - completed");
/*TRIAC command - configuration*/
ESP_LOGI(TAG, "Triac command configuration");
gpio_set_direction(dimOutPin[ptr->current_num], GPIO_MODE_OUTPUT);
ESP_LOGI(TAG, "Triac command configuration - completed");
}
/*ISR debug region*/
#if DEBUG_ISR_DIMMER == ISR_DEBUG_ON
static xQueueHandle gpio_zero_cross_evt_queue = NULL;
static void gpio_isr_zerocross_debug(void *arg)
{
uint32_t io_num;
for (;;)
{
if (xQueueReceive(gpio_zero_cross_evt_queue, &io_num, portMAX_DELAY))
{
ESP_LOGI(TAG, "Zero-cross trigger fired");
}
}
}
#endif
/*ISR timer debug region*/
#if DEBUG_ISR_TIMER == ISR_DEBUG_ON
static xQueueHandle timer_event_queue = NULL;
static void timer_isr_debug(void *arg)
{
uint32_t io_num;
for (;;)
{
if (xQueueReceive(timer_event_queue, &io_num, portMAX_DELAY))
{
printf("Timer interrupt event , counter = %5d \n", io_num);
}
}
}
#endif
void begin(dimmertyp *ptr, DIMMER_MODE_typedef DIMMER_MODE, ON_OFF_typedef ON_OFF, int FREQ)
{
ESP_LOGI(TAG, "Dimmer - begin");
dimMode[ptr->current_num] = DIMMER_MODE;
dimState[ptr->current_num] = ON_OFF;
#if DEBUG_ISR_DIMMER == ISR_DEBUG_ON
if (!_initDone)
{
// create a queue to handle gpio event from isr
gpio_zero_cross_evt_queue = xQueueCreate(10, sizeof(uint32_t));
// start gpio task
xTaskCreate(gpio_isr_zerocross_debug, "gpio_isr_debug", 2048, NULL, 10, NULL);
}
#endif
#if DEBUG_ISR_TIMER == ISR_DEBUG_ON
if (!_initDone)
{
// create a queue to handle timer event
timer_event_queue = xQueueCreate(10, sizeof(uint32_t));
// start gpio task
xTaskCreate(timer_isr_debug, "timer_isr_debug", 2048, NULL, 10, NULL);
}
#endif
config_timer(FREQ);
ext_int_init(ptr);
// init completed
_initDone = true;
ESP_LOGI(TAG, "Dimmer begin - completed");
}
void setPower(dimmertyp *ptr, int power)
{
if (power >= 99)
{
power = 99;
}
dimPower[ptr->current_num] = power;
dimPulseBegin[ptr->current_num] = powerBuf[power];
vTaskDelay(1);
}
int getPower(dimmertyp *ptr)
{
if (dimState[ptr->current_num] == ON)
return dimPower[ptr->current_num];
else
return 0;
}
void setState(dimmertyp *ptr, ON_OFF_typedef ON_OFF)
{
dimState[ptr->current_num] = ON_OFF;
}
bool getState(dimmertyp *ptr)
{
bool ret;
if (dimState[ptr->current_num] == ON)
ret = true;
else
ret = false;
return ret;
}
void changeState(dimmertyp *ptr)
{
if (dimState[ptr->current_num] == ON)
dimState[ptr->current_num] = OFF;
else
dimState[ptr->current_num] = ON;
}
DIMMER_MODE_typedef getMode(dimmertyp *ptr)
{
return dimMode[ptr->current_num];
}
void setMode(dimmertyp *ptr, DIMMER_MODE_typedef DIMMER_MODE)
{
dimMode[ptr->current_num] = DIMMER_MODE;
}
void toggleSettings(dimmertyp *ptr, int minValue, int maxValue)
{
if (maxValue > 99)
{
maxValue = 99;
}
if (minValue < 1)
{
minValue = 1;
}
dimMode[ptr->current_num] = TOGGLE_MODE;
togMin[ptr->current_num] = powerBuf[maxValue];
togMax[ptr->current_num] = powerBuf[minValue];
toggleReload = 50;
}
static void IRAM_ATTR isr_ext(void *arg)
{
#if DEBUG_ISR_DIMMER == ISR_DEBUG_ON
uint32_t gpio_num = (uint32_t)arg;
xQueueSendFromISR(gpio_zero_cross_evt_queue, &gpio_num, NULL);
#endif
for (int i = 0; i < current_dim; i++)
if (dimState[i] == ON)
{
zeroCross[i] = 1;
}
}
static int k;
#if DEBUG_ISR_TIMER == ISR_DEBUG_ON
static int counter = 0;
#endif
/* Execution on timer event */
static void IRAM_ATTR onTimerISR(void *para)
{
/*Block needed to handle timer ISR*/
timer_spinlock_take(TIMER_GROUP_0);
timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
/*Give back spinlock at the end of the method*/
/**********************************/
#if DEBUG_ISR_TIMER == ISR_DEBUG_ON
counter++;
uint32_t info = (uint32_t)counter;
xQueueSendFromISR(timer_event_queue, &info, NULL);
#endif
toggleCounter++;
for (k = 0; k < current_dim; k++)
{
if (zeroCross[k] == 1)
{
dimCounter[k]++;
if (dimMode[k] == TOGGLE_MODE)
{
/*****
* TOGGLE DIMMING MODE
*****/
if (dimPulseBegin[k] >= togMax[k])
{
// if reach max dimming value
togDir[k] = false; // downcount
}
if (dimPulseBegin[k] <= togMin[k])
{
// if reach min dimming value
togDir[k] = true; // upcount
}
if (toggleCounter == toggleReload)
{
if (togDir[k] == true)
dimPulseBegin[k]++;
else
dimPulseBegin[k]--;
}
}
/*****
* DEFAULT DIMMING MODE (NOT TOGGLE)
*****/
if (dimCounter[k] >= dimPulseBegin[k])
{
gpio_set_level(dimOutPin[k], 1);
}
if (dimCounter[k] >= (dimPulseBegin[k] + pulseWidth))
{
gpio_set_level(dimOutPin[k], 0);
zeroCross[k] = 0;
dimCounter[k] = 0;
}
}
}
if (toggleCounter >= toggleReload)
toggleCounter = 1;
/* After the alarm has been triggered
we need enable it again, so it is triggered the next time */
timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0);
timer_spinlock_give(TIMER_GROUP_0);
}

View File

@@ -1,87 +0,0 @@
#ifndef RBDDIMMER_H
#define RBDDIMMER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "driver/timer.h"
#include "freertos/task.h"
#include "math.h"
#include "esp_log.h"
#define ALL_DIMMERS 50
/*ISR debug defines*/
#define ISR_DEBUG_ON 1
#define ISR_DEBUG_OFF 0
/*Activate/Deactivate isr debug*/
#define DEBUG_ISR_DIMMER ISR_DEBUG_OFF
/*If timer is too fast can lead to core 0 panic*/
#define DEBUG_ISR_TIMER ISR_DEBUG_OFF
static const uint8_t powerBuf[] = {
100, 99, 98, 97, 96, 95, 94, 93, 92, 91,
90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
70, 69, 68, 67, 66, 65, 64, 63, 62, 61,
60, 59, 58, 57, 56, 55, 54, 53, 52, 51,
50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
#define ESP_INTR_FLAG_DEFAULT 0
typedef enum
{
NORMAL_MODE = 0,
TOGGLE_MODE = 1
} DIMMER_MODE_typedef;
typedef enum
{
OFF = false,
ON = true
} ON_OFF_typedef;
typedef struct dimmer
{
int current_num;
int timer_num;
bool toggle_state;
int tog_current;
int steps;
uint16_t pulse_begin;
int dimmer_pin;
int tog_max;
int tog_min;
int zc_pin;
} dimmertyp;
dimmertyp *createDimmer(gpio_num_t user_dimmer_pin, gpio_num_t zc_dimmer_pin);
void begin(dimmertyp *ptr, DIMMER_MODE_typedef DIMMER_MODE, ON_OFF_typedef ON_OFF, int FREQ);
void setPower(dimmertyp *ptr, int power);
int getPower(dimmertyp *ptr);
void setState(dimmertyp *ptr, ON_OFF_typedef ON_OFF);
bool getState(dimmertyp *ptr);
void changeState(dimmertyp *ptr);
void setMode(dimmertyp *ptr, DIMMER_MODE_typedef DIMMER_MODE);
DIMMER_MODE_typedef getMode(dimmertyp *ptr);
void toggleSettings(dimmertyp *ptr, int minValue, int maxValue);
void port_init(dimmertyp *ptr);
void config_timer(int freq);
void ext_int_init(dimmertyp *ptr);
static void IRAM_ATTR isr_ext(void* arg);
static void IRAM_ATTR onTimerISR(void* arg);
#endif