mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-21 17:16:29 +08:00
refactor(hw_timer): Refactor hw_timer driver for esp8266 idf
This commit is contained in:
245
components/esp8266/driver/hw_timer.c
Normal file
245
components/esp8266/driver/hw_timer.c
Normal file
@ -0,0 +1,245 @@
|
||||
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "esp8266/timer_struct.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "driver/hw_timer.h"
|
||||
|
||||
#define ENTER_CRITICAL() portENTER_CRITICAL()
|
||||
#define EXIT_CRITICAL() portEXIT_CRITICAL()
|
||||
|
||||
static const char *TAG = "hw_timer";
|
||||
|
||||
#define HW_TIMER_CHECK(a, str, ret_val) \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
|
||||
#define hw_timer_intr_enable() _xt_isr_unmask(1 << ETS_FRC_TIMER1_INUM)
|
||||
|
||||
#define hw_timer_intr_disable() _xt_isr_mask(1 << ETS_FRC_TIMER1_INUM)
|
||||
|
||||
#define hw_timer_intr_register(a, b) _xt_isr_attach(ETS_FRC_TIMER1_INUM, (a), (b))
|
||||
|
||||
|
||||
typedef struct {
|
||||
hw_timer_callback_t cb;
|
||||
} hw_timer_obj_t;
|
||||
|
||||
hw_timer_obj_t *hw_timer_obj = NULL;
|
||||
|
||||
esp_err_t hw_timer_set_clkdiv(hw_timer_clkdiv_t clkdiv)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
HW_TIMER_CHECK(clkdiv >= TIMER_CLKDIV_1 && clkdiv <= TIMER_CLKDIV_256, "clkdiv is out of range.", ESP_ERR_INVALID_ARG);
|
||||
|
||||
ENTER_CRITICAL();
|
||||
frc1.ctrl.div = clkdiv;
|
||||
EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t hw_timer_get_clkdiv()
|
||||
{
|
||||
return frc1.ctrl.div;
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_set_intr_type(hw_timer_intr_type_t intr_type)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
HW_TIMER_CHECK(intr_type >= TIMER_EDGE_INT && intr_type <= TIMER_LEVEL_INT, "intr_type is out of range.", ESP_ERR_INVALID_ARG);
|
||||
|
||||
ENTER_CRITICAL();
|
||||
frc1.ctrl.intr_type = intr_type;
|
||||
EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t hw_timer_get_intr_type()
|
||||
{
|
||||
return frc1.ctrl.intr_type;
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_set_reload(bool reload)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
|
||||
ENTER_CRITICAL();
|
||||
if (true == reload) {
|
||||
frc1.ctrl.reload = 0x01;
|
||||
} else {
|
||||
frc1.ctrl.reload = 0x00;
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
}
|
||||
|
||||
bool hw_timer_get_reload()
|
||||
{
|
||||
if (frc1.ctrl.reload) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_enable(bool en)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
|
||||
ENTER_CRITICAL();
|
||||
if (true == en) {
|
||||
frc1.ctrl.en = 0x01;
|
||||
} else {
|
||||
frc1.ctrl.en = 0x00;
|
||||
}
|
||||
EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool hw_timer_get_enable()
|
||||
{
|
||||
if (frc1.ctrl.en) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_set_load_data(uint32_t load_data)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
HW_TIMER_CHECK(load_data < 0x1000000, "load_data is out of range.", ESP_ERR_INVALID_ARG);
|
||||
|
||||
ENTER_CRITICAL();
|
||||
frc1.load.data = load_data;
|
||||
EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t hw_timer_get_load_data()
|
||||
{
|
||||
return frc1.load.data;
|
||||
}
|
||||
|
||||
uint32_t hw_timer_get_count_data()
|
||||
{
|
||||
return frc1.count.data;
|
||||
}
|
||||
|
||||
static void hw_timer_isr_cb(void* arg)
|
||||
{
|
||||
if (!frc1.ctrl.reload) {
|
||||
frc1.ctrl.en = 0;
|
||||
}
|
||||
if (hw_timer_obj->cb != NULL) {
|
||||
hw_timer_obj->cb(arg);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_disarm(void)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
|
||||
frc1.ctrl.val = 0;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_alarm_us(uint32_t value, bool reload)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
HW_TIMER_CHECK( (reload ? ((value > 50) ? 1 : 0) : ((value > 10) ? 1 : 0)) && (value <= 0x199999), "value is out of range.", ESP_ERR_INVALID_ARG);
|
||||
|
||||
hw_timer_set_reload(reload);
|
||||
hw_timer_set_clkdiv(TIMER_CLKDIV_16);
|
||||
hw_timer_set_intr_type(TIMER_EDGE_INT);
|
||||
hw_timer_set_load_data(((TIMER_BASE_CLK >> hw_timer_get_clkdiv()) / 1000000) * value); // Calculate the number of timer clocks required for timing, ticks = (80MHz / div) * t
|
||||
hw_timer_enable(true);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void hw_timer_obj_delete(void)
|
||||
{
|
||||
if (NULL == hw_timer_obj) {
|
||||
return;
|
||||
}
|
||||
hw_timer_obj->cb = NULL;
|
||||
heap_caps_free(hw_timer_obj);
|
||||
hw_timer_obj = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t hw_timer_obj_create(void)
|
||||
{
|
||||
hw_timer_obj = (hw_timer_obj_t *)heap_caps_malloc(sizeof(hw_timer_obj_t), MALLOC_CAP_8BIT);
|
||||
|
||||
if (NULL == hw_timer_obj) {
|
||||
hw_timer_obj_delete();
|
||||
return ESP_FAIL;
|
||||
}
|
||||
hw_timer_obj->cb = NULL;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_deinit(void)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj, "hw_timer has not been initialized yet", ESP_FAIL);
|
||||
|
||||
hw_timer_disarm();
|
||||
hw_timer_intr_disable();
|
||||
TM1_EDGE_INT_DISABLE();
|
||||
hw_timer_intr_register(NULL, NULL);
|
||||
hw_timer_obj_delete();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hw_timer_init(hw_timer_callback_t callback, void *arg)
|
||||
{
|
||||
HW_TIMER_CHECK(hw_timer_obj == NULL, "hw_timer has been initialized", ESP_FAIL);
|
||||
HW_TIMER_CHECK(callback != NULL, "callback pointer NULL", ESP_ERR_INVALID_ARG);
|
||||
|
||||
if (ESP_FAIL == hw_timer_obj_create()) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
hw_timer_obj->cb = callback;
|
||||
hw_timer_intr_register(hw_timer_isr_cb, arg);
|
||||
TM1_EDGE_INT_ENABLE();
|
||||
hw_timer_intr_enable();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
198
components/esp8266/include/driver/hw_timer.h
Normal file
198
components/esp8266/include/driver/hw_timer.h
Normal file
@ -0,0 +1,198 @@
|
||||
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TIMER_BASE_CLK APB_CLK_FREQ
|
||||
|
||||
typedef void (*hw_timer_callback_t)(void *arg);
|
||||
|
||||
typedef enum {
|
||||
TIMER_CLKDIV_1 = 0,
|
||||
TIMER_CLKDIV_16 = 4,
|
||||
TIMER_CLKDIV_256 = 8
|
||||
} hw_timer_clkdiv_t;
|
||||
|
||||
typedef enum {
|
||||
TIMER_EDGE_INT = 0, // edge interrupt
|
||||
TIMER_LEVEL_INT = 1 // level interrupt
|
||||
} hw_timer_intr_type_t;
|
||||
|
||||
/**
|
||||
* @brief Set the frequency division coefficient of hardware timer
|
||||
*
|
||||
* @param clkdiv frequency division coefficient
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL hardware timer has been initialized
|
||||
*/
|
||||
esp_err_t hw_timer_set_clkdiv(hw_timer_clkdiv_t clkdiv);
|
||||
|
||||
/**
|
||||
* @brief Get the frequency division coefficient of hardware timer
|
||||
*
|
||||
* @return
|
||||
* - 0 TIMER_CLKDIV_1
|
||||
* - 4 TIMER_CLKDIV_16
|
||||
* - 8 TIMER_CLKDIV_256
|
||||
*/
|
||||
uint32_t hw_timer_get_clkdiv();
|
||||
|
||||
/**
|
||||
* @brief Set the interrupt type of hardware timer
|
||||
*
|
||||
* @param intr_type interrupt type
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL hardware timer has been initialized
|
||||
*/
|
||||
esp_err_t hw_timer_set_intr_type(hw_timer_intr_type_t intr_type);
|
||||
|
||||
/**
|
||||
* @brief Get the interrupt type of hardware timer
|
||||
*
|
||||
* @return
|
||||
* - 0 TIMER_EDGE_INT
|
||||
* - 1 TIMER_LEVEL_INT
|
||||
*/
|
||||
uint32_t hw_timer_get_intr_type();
|
||||
|
||||
/**
|
||||
* @brief Enable hardware timer reload
|
||||
*
|
||||
* @param reload false, one-shot mode; true, reload mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL hardware timer has been initialized
|
||||
*/
|
||||
esp_err_t hw_timer_set_reload(bool reload);
|
||||
|
||||
/**
|
||||
* @brief Get the hardware timer reload status
|
||||
*
|
||||
* @return
|
||||
* - true reload mode
|
||||
* - false one-shot mode
|
||||
*/
|
||||
bool hw_timer_get_reload();
|
||||
|
||||
/**
|
||||
* @brief Enable hardware timer
|
||||
*
|
||||
* @param en false, hardware timer disable; true, hardware timer enable
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL hardware timer has been initialized
|
||||
*/
|
||||
esp_err_t hw_timer_enable(bool en);
|
||||
|
||||
/**
|
||||
* @brief Get the hardware timer enable status
|
||||
*
|
||||
* @return
|
||||
* - true hardware timer has been enabled
|
||||
* - false hardware timer is not yet enabled
|
||||
*/
|
||||
bool hw_timer_get_enable();
|
||||
|
||||
/**
|
||||
* @brief Set the hardware timer load value
|
||||
*
|
||||
* @param load_data hardware timer load value
|
||||
* - FRC1 hardware timer, range : less than 0x1000000
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL hardware timer has been initialized
|
||||
*/
|
||||
esp_err_t hw_timer_set_load_data(uint32_t load_data);
|
||||
|
||||
/**
|
||||
* @brief Get the hardware timer load value
|
||||
*
|
||||
* @return load value
|
||||
*/
|
||||
uint32_t hw_timer_get_load_data();
|
||||
|
||||
/**
|
||||
* @brief Get the hardware timer count value
|
||||
*
|
||||
* @return count value
|
||||
*/
|
||||
uint32_t hw_timer_get_count_data();
|
||||
|
||||
/**
|
||||
* @brief deinit the hardware timer
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL hardware timer has not been initialized yet
|
||||
*/
|
||||
esp_err_t hw_timer_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware timer
|
||||
*
|
||||
* @param callback user hardware timer callback function
|
||||
* @param arg parameter for ISR handler
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL hardware timer has been initialized
|
||||
*/
|
||||
esp_err_t hw_timer_init(hw_timer_callback_t callback, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Set a trigger timer us delay to enable this timer
|
||||
*
|
||||
* @param value
|
||||
* - If reload is true, range : 50 ~ 0x199999
|
||||
* - If reload is false, range : 10 ~ 0x199999
|
||||
* @param reload false, one-shot mode; true, reload mode.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL hardware timer has not been initialized yet
|
||||
*/
|
||||
|
||||
esp_err_t hw_timer_alarm_us(uint32_t value, bool reload);
|
||||
|
||||
/**
|
||||
* @brief disable this timer
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL hardware timer has not been initialized yet
|
||||
*/
|
||||
esp_err_t hw_timer_disarm(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
70
components/esp8266/include/esp8266/timer_struct.h
Normal file
70
components/esp8266/include/esp8266/timer_struct.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp8266/eagle_soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ESP8266 FRC Register Definitions */
|
||||
|
||||
// FRC1 is a 24-bit countdown timer, triggers interrupt when reaches zero.
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t data: 23;
|
||||
uint32_t reserved23: 9;
|
||||
};
|
||||
uint32_t val;
|
||||
} load;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t data: 23;
|
||||
uint32_t reserved23: 9;
|
||||
};
|
||||
uint32_t val;
|
||||
} count;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t div: 6;
|
||||
uint32_t reload: 1;
|
||||
uint32_t en: 1;
|
||||
uint32_t intr_type: 1;
|
||||
uint32_t reserved24: 23;
|
||||
};
|
||||
uint32_t val;
|
||||
} ctrl;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t clr: 1;
|
||||
uint32_t reserved1: 31;
|
||||
};
|
||||
uint32_t val;
|
||||
} intr;
|
||||
} frc1_struct_t;
|
||||
|
||||
extern volatile frc1_struct_t frc1;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* end of __cplusplus */
|
||||
|
@ -2,3 +2,5 @@ PROVIDE ( GPIO = 0x60000300);
|
||||
|
||||
PROVIDE ( uart0 = 0x60000000 );
|
||||
PROVIDE ( uart1 = 0x60000f00 );
|
||||
|
||||
PROVIDE ( frc1 = 0x60000600 );
|
9
examples/peripherals/hw_timer/Makefile
Normal file
9
examples/peripherals/hw_timer/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := hw_timer
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
56
examples/peripherals/hw_timer/README.md
Normal file
56
examples/peripherals/hw_timer/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
# _HW_TIMER Example_
|
||||
|
||||
* This example will show you how to use hw_timer by led or logic analyzer:
|
||||
* Using hw_timer to generate waveforms of different frequencies
|
||||
* Observe the waveform with led or logic analyzer.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* Connect GPIO12 with led1
|
||||
* Connect GPIO15 with led2
|
||||
|
||||
### Configure the project
|
||||
|
||||
```
|
||||
make menuconfig
|
||||
```
|
||||
|
||||
* Set serial port under Serial Flasher Options.
|
||||
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
make -j4 flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
## Example Output
|
||||
|
||||
* LOG:
|
||||
|
||||
```
|
||||
I (228) hw_timer_example: Config gpio
|
||||
I (220) gpio: GPIO[12]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (224) gpio: GPIO[15]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (248) hw_timer_example: Initialize hw_timer for callback1
|
||||
I (258) hw_timer_example: Set hw_timer timing time 100us with reload
|
||||
I (1268) hw_timer_example: Deinitialize hw_timer for callback1
|
||||
I (1261) hw_timer_example: Initialize hw_timer for callback2
|
||||
I (1264) hw_timer_example: Set hw_timer timing time 1ms with reload
|
||||
I (2278) hw_timer_example: Set hw_timer timing time 10ms with reload
|
||||
I (4278) hw_timer_example: Set hw_timer timing time 100ms with reload
|
||||
I (7278) hw_timer_example: Cancel timing
|
||||
I (7270) hw_timer_example: Initialize hw_timer for callback3
|
||||
I (7272) hw_timer_example: Set hw_timer timing time 1ms with one-shot
|
||||
|
||||
```
|
||||
|
||||
* WAVE FORM:
|
||||
|
||||

|
3
examples/peripherals/hw_timer/main/component.mk
Normal file
3
examples/peripherals/hw_timer/main/component.mk
Normal file
@ -0,0 +1,3 @@
|
||||
#
|
||||
# Main Makefile. This is basically the same as a component makefile.
|
||||
#
|
91
examples/peripherals/hw_timer/main/hw_timer_example_main.c
Normal file
91
examples/peripherals/hw_timer/main/hw_timer_example_main.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* hw_timer 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 "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/hw_timer.h"
|
||||
|
||||
static const char *TAG = "hw_timer_example";
|
||||
|
||||
#define TEST_ONE_SHOT false // testing will be done without auto reload (one-shot)
|
||||
#define TEST_RELOAD true // testing will be done with auto reload
|
||||
|
||||
#define GPIO_OUTPUT_IO_0 12
|
||||
#define GPIO_OUTPUT_IO_1 15
|
||||
#define GPIO_OUTPUT_PIN_SEL ((1ULL << GPIO_OUTPUT_IO_0) | (1ULL << GPIO_OUTPUT_IO_1))
|
||||
|
||||
void hw_timer_callback1(void *arg)
|
||||
{
|
||||
static int state = 0;
|
||||
|
||||
gpio_set_level(GPIO_OUTPUT_IO_0, (state ++) % 2);
|
||||
}
|
||||
|
||||
void hw_timer_callback2(void *arg)
|
||||
{
|
||||
static int state = 0;
|
||||
|
||||
gpio_set_level(GPIO_OUTPUT_IO_1, (state ++) % 2);
|
||||
}
|
||||
|
||||
void hw_timer_callback3(void *arg)
|
||||
{
|
||||
gpio_set_level(GPIO_OUTPUT_IO_0, 0);
|
||||
gpio_set_level(GPIO_OUTPUT_IO_1, 1);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Config gpio");
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
ESP_LOGI(TAG, "Initialize hw_timer for callback1");
|
||||
hw_timer_init(hw_timer_callback1, NULL);
|
||||
ESP_LOGI(TAG, "Set hw_timer timing time 100us with reload");
|
||||
hw_timer_alarm_us(100, TEST_RELOAD);
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_LOGI(TAG, "Deinitialize hw_timer for callback1");
|
||||
hw_timer_deinit();
|
||||
|
||||
ESP_LOGI(TAG, "Initialize hw_timer for callback2");
|
||||
hw_timer_init(hw_timer_callback2, NULL);
|
||||
ESP_LOGI(TAG, "Set hw_timer timing time 1ms with reload");
|
||||
hw_timer_alarm_us(1000, TEST_RELOAD);
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
ESP_LOGI(TAG, "Set hw_timer timing time 10ms with reload");
|
||||
hw_timer_alarm_us(10000, TEST_RELOAD);
|
||||
vTaskDelay(2000 / portTICK_RATE_MS);
|
||||
ESP_LOGI(TAG, "Set hw_timer timing time 100ms with reload");
|
||||
hw_timer_alarm_us(100000, TEST_RELOAD);
|
||||
vTaskDelay(3000 / portTICK_RATE_MS);
|
||||
ESP_LOGI(TAG, "Cancel timing");
|
||||
hw_timer_disarm();
|
||||
hw_timer_deinit();
|
||||
|
||||
ESP_LOGI(TAG, "Initialize hw_timer for callback3");
|
||||
hw_timer_init(hw_timer_callback3, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "Set hw_timer timing time 1ms with one-shot");
|
||||
hw_timer_alarm_us(1000, TEST_ONE_SHOT);
|
||||
}
|
||||
|
||||
|
BIN
examples/peripherals/hw_timer/wave.png
Normal file
BIN
examples/peripherals/hw_timer/wave.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 895 B |
Reference in New Issue
Block a user