driver: sigma-delta

1. add sigma-delta code and example.
2. add gpio output signal in io matrix.

Squashed commits:
[a25e7d4] minor changes for doc
[6a03a1e] minor changes on comments and doc.
[97dd9e4] Add doc.
update index.rst
change example index
pull/155/merge
Wangjialin 2016-11-23 16:28:16 +08:00
rodzic 576052e5c2
commit b00b75db7e
9 zmienionych plików z 291 dodań i 1 usunięć

Wyświetl plik

@ -292,6 +292,7 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig)
}
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
output_en = 1;
gpio_matrix_out(io_num, SIG_GPIO_OUT_IDX, 0, 0);
gpio_output_enable(io_num);
} else {
gpio_output_disable(io_num);

Wyświetl plik

@ -0,0 +1,108 @@
// Copyright 2015-2016 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.
#ifndef __DRIVER_SIGMADELTA_H__
#define __DRIVER_SIGMADELTA_H__
#include <esp_types.h>
#include "soc/gpio_sd_struct.h"
#include "soc/gpio_sd_reg.h"
#include "driver/gpio.h"
#ifdef _cplusplus
extern "C" {
#endif
/**
* @brief Sigma-delta channel list
*/
typedef enum{
SIGMADELTA_CHANNEL_0 = 0, /*!< Sigma-delta channel0 */
SIGMADELTA_CHANNEL_1 = 1, /*!< Sigma-delta channel1 */
SIGMADELTA_CHANNEL_2 = 2, /*!< Sigma-delta channel2 */
SIGMADELTA_CHANNEL_3 = 3, /*!< Sigma-delta channel3 */
SIGMADELTA_CHANNEL_4 = 4, /*!< Sigma-delta channel4 */
SIGMADELTA_CHANNEL_5 = 5, /*!< Sigma-delta channel5 */
SIGMADELTA_CHANNEL_6 = 6, /*!< Sigma-delta channel6 */
SIGMADELTA_CHANNEL_7 = 7, /*!< Sigma-delta channel7 */
SIGMADELTA_CHANNEL_MAX,
} sigmadelta_channel_t;
/**
* @brief Sigma-delta configure struct
*/
typedef struct {
sigmadelta_channel_t channel; /*!< Sigma-delta channel number */
int8_t sigmadelta_duty; /*!< Sigma-delta duty, duty ranges from -128 to 127. */
uint8_t sigmadelta_prescale; /*!< Sigma-delta prescale, prescale ranges from 0 to 255. */
uint8_t sigmadelta_gpio; /*!< Sigma-delta output io number, refer to gpio.h for more details. */
} sigmadelta_config_t;
/**
* @brief Configure Sigma-delta channel
*
* @param config Pointer of Sigma-delta channel configuration struct
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t sigmadelta_config(sigmadelta_config_t *config);
/**
* @brief Set Sigma-delta channel duty.
*
* This function is used to set Sigma-delta channel duty,
* If you add a capacitor between the output pin and ground,
* the average output voltage Vdc = VDDIO / 256 * duty + VDDIO/2, VDDIO is power supply voltage.
*
* @param channel Sigma-delta channel number
* @param duty Sigma-delta duty of one channel, the value ranges from -128 to 127, recommended range is -90 ~ 90.
* The waveform is more like a random one in this range.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t sigmadelta_set_duty(sigmadelta_channel_t channel, int8_t duty);
/**
* @brief Set Sigma-delta channel's clock pre-scale value.
* The source clock is APP_CLK, 80MHz. The clock frequency of the sigma-delta channel is APP_CLK / pre_scale
*
* @param channel Sigma-delta channel number
* @param prescale The divider of source clock, ranges from 0 to 255
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t sigmadelta_set_prescale(sigmadelta_channel_t channel, uint8_t prescale);
/**
* @brief Set Sigma-delta signal output pin
*
* @param channel Sigma-delta channel number
* @param gpio_num GPIO number of output pin.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t sigmadelta_set_pin(sigmadelta_channel_t channel, gpio_num_t gpio_num);
#ifdef _cplusplus
}
#endif
#endif

Wyświetl plik

@ -0,0 +1,61 @@
// Copyright 2015-2016 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 "esp_log.h"
#include "soc/soc.h"
#include "driver/periph_ctrl.h"
#include "driver/sigmadelta.h"
static const char* SIGMADELTA_TAG = "SIGMADELTA";
#define SIGMADELTA_CHANNEL_ERR_STR "SIGMADELTA CHANNEL ERROR"
#define SIGMADELTA_IO_ERR_STR "SIGMADELTA GPIO NUM ERROR"
#define SIGMADELTA_CHECK(a,str,ret_val) if(!(a)) { \
ESP_LOGE(SIGMADELTA_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret_val); \
}
esp_err_t sigmadelta_config(sigmadelta_config_t *config)
{
SIGMADELTA_CHECK(config->channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
SIGMADELTA_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(config->sigmadelta_gpio), SIGMADELTA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
sigmadelta_set_duty(config->channel, config->sigmadelta_duty);
sigmadelta_set_prescale(config->channel, config->sigmadelta_prescale);
sigmadelta_set_pin(config->channel, config->sigmadelta_gpio);
return ESP_OK;
}
esp_err_t sigmadelta_set_duty(sigmadelta_channel_t channel, int8_t duty)
{
SIGMADELTA_CHECK(channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
SIGMADELTA.channel[channel].duty = duty;
return ESP_OK;
}
esp_err_t sigmadelta_set_prescale(sigmadelta_channel_t channel, uint8_t prescale)
{
SIGMADELTA_CHECK(channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
SIGMADELTA.channel[channel].prescale = prescale;
return ESP_OK;
}
esp_err_t sigmadelta_set_pin(sigmadelta_channel_t channel, gpio_num_t gpio_num)
{
SIGMADELTA_CHECK(channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
SIGMADELTA_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), SIGMADELTA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
gpio_matrix_out(gpio_num, GPIO_SD0_OUT_IDX + channel, 0, 0);
return ESP_OK;
}

Wyświetl plik

@ -418,5 +418,5 @@
#define SIG_IN_FUNC226_IDX 226
#define SIG_IN_FUNC227_IDX 227
#define SIG_IN_FUNC228_IDX 228
#define SIG_GPIO_OUT_IDX 256
#endif /* _SOC_GPIO_SIG_MAP_H_ */

Wyświetl plik

@ -0,0 +1,51 @@
Sigma-delta Modulation
========
Overview
--------
ESP32 has a second-order sigma-delta modulation module.
This driver configures the channels of the sigma-delta module.
Application Example
-------------------
Sigma-delta Modulation example: `examples/14_sigmadelta <https://github.com/espressif/esp-idf/tree/master/examples/14_sigmadelta>`_.
API Reference
-------------
Header Files
^^^^^^^^^^^^
* `driver/sigmadelta.h <https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/sigmadelta.h>`_
Macros
^^^^^^
Type Definitions
^^^^^^^^^^^^^^^^
Enumerations
^^^^^^^^^^^^
.. doxygenenum:: sigmadelta_channel_t
Structures
^^^^^^^^^^
.. doxygenstruct:: sigmadelta_config_t
:members:
Functions
^^^^^^^^^
.. doxygenfunction:: sigmadelta_config
.. doxygenfunction:: sigmadelta_set_duty
.. doxygenfunction:: sigmadelta_set_prescale
.. doxygenfunction:: sigmadelta_set_pin

1
docs/index.rst 100755 → 100644
Wyświetl plik

@ -108,6 +108,7 @@ Contents:
Remote Control <api/rmt>
Timer <api/timer>
Pulse Counter <api/pcnt>
Sigma-delta Modulation <api/sigmadelta>
SPI Flash and Partition APIs <api/spi_flash>
Logging <api/log>
Non-Volatile Storage <api/nvs_flash>

Wyświetl plik

@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := sigmadelta
include $(IDF_PATH)/make/project.mk

Wyświetl plik

@ -0,0 +1,5 @@
#
# Main Makefile. This is basically the same as a component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

Wyświetl plik

@ -0,0 +1,54 @@
/* Sigma-delta 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 "esp_system.h"
#include "driver/sigmadelta.h"
/*
* This test code intended to configure sigma-delta and set GPIO4 as signal output pin.
* If you connect this GPIO4 with an LED, you will see the LED blinking slowly.
*/
/**
* @brief Sigma-delta initialization.
*/
static void sigmadelta_init(void)
{
sigmadelta_config_t sigmadelta_cfg = {
/* Sigma-delta channel0*/
.channel = SIGMADELTA_CHANNEL_0,
/* Sigma-delta set duty 10*/
.sigmadelta_duty = 10,
/* Set prescale 30 */
.sigmadelta_prescale = 80,
/*select GPIO4 as output_io */
.sigmadelta_gpio = 4,
};
sigmadelta_config(&sigmadelta_cfg);
}
/**
* @brief Sigma-delta test to change duty of output signal.
*/
void app_main()
{
sigmadelta_init();
int8_t duty = 0;
int inc = 1;
while(1) {
sigmadelta_set_duty(SIGMADELTA_CHANNEL_0, duty);
/*by changing delay time, you can change the blink frequency of LED. */
vTaskDelay(10 / portTICK_RATE_MS);
duty += inc;
if(duty == 127 || duty == -127) inc = (-1) * inc;
}
}