]> granicus.if.org Git - esp-idf/commitdiff
driver: sigma-delta
authorWangjialin <wangjialin@espressif.com>
Wed, 23 Nov 2016 08:28:16 +0000 (16:28 +0800)
committerWangjialin <wangjialin@espressif.com>
Sun, 18 Dec 2016 09:20:17 +0000 (17:20 +0800)
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

components/driver/gpio.c
components/driver/include/driver/sigmadelta.h [new file with mode: 0644]
components/driver/sigmadelta.c [new file with mode: 0644]
components/esp32/include/soc/gpio_sig_map.h
docs/api/sigmadelta.rst [new file with mode: 0644]
docs/index.rst [changed mode: 0755->0644]
examples/19_sigmadelta/Makefile [new file with mode: 0644]
examples/19_sigmadelta/main/component.mk [new file with mode: 0644]
examples/19_sigmadelta/main/sigmadelta_test.c [new file with mode: 0644]

index 4bdd716f362f8a3de9c103c442147942af9167fe..1a38620dbb525991bb28914067090d5ff23dddde 100644 (file)
@@ -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);
diff --git a/components/driver/include/driver/sigmadelta.h b/components/driver/include/driver/sigmadelta.h
new file mode 100644 (file)
index 0000000..db16783
--- /dev/null
@@ -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
diff --git a/components/driver/sigmadelta.c b/components/driver/sigmadelta.c
new file mode 100644 (file)
index 0000000..09969e6
--- /dev/null
@@ -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;
+}
+
index dad22f92f8cb37e718bb04359f795c606e1d2ce9..4d2943fb9fa791776534cd8d72e75dde66bbc684 100644 (file)
 #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_ */
diff --git a/docs/api/sigmadelta.rst b/docs/api/sigmadelta.rst
new file mode 100644 (file)
index 0000000..acfdaaa
--- /dev/null
@@ -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
+
old mode 100755 (executable)
new mode 100644 (file)
index 901187d..ba25b49
@@ -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>
diff --git a/examples/19_sigmadelta/Makefile b/examples/19_sigmadelta/Makefile
new file mode 100644 (file)
index 0000000..75f7111
--- /dev/null
@@ -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
+
diff --git a/examples/19_sigmadelta/main/component.mk b/examples/19_sigmadelta/main/component.mk
new file mode 100644 (file)
index 0000000..4d3b30c
--- /dev/null
@@ -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.)
+
diff --git a/examples/19_sigmadelta/main/sigmadelta_test.c b/examples/19_sigmadelta/main/sigmadelta_test.c
new file mode 100644 (file)
index 0000000..92bc6e0
--- /dev/null
@@ -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;
+    }
+}