Merge branch 'driver_merge_tmp/merge_rtc_module' into 'master'

Driver: add rtc module

1. add rtc io control API (pull,output and input)
2. add touch pad API (touch pad read and interrupt)
3. add adc1 API (the max width is 12 Bits and support attenuation)
4. add hall sensor API (support hall sensor read )
5. add dac API (the width is 8 Bits)

See merge request !243
This commit is contained in:
Ivan Grokhotkov 2016-12-07 17:03:33 +08:00
commit 6dc77bc55c
12 changed files with 4289 additions and 3130 deletions

View File

@ -17,6 +17,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "soc/soc.h"
#include "esp_log.h"
@ -69,74 +70,45 @@ const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
GPIO_PIN_REG_39
};
const gpio_pu_pd_desc_t gpio_pu_pd_desc[GPIO_PIN_COUNT]={
{RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M},
{PERIPHS_IO_MUX_U0TXD_U, FUN_PU, FUN_PD},
{RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M},
{PERIPHS_IO_MUX_U0RXD_U, FUN_PU, FUN_PD},
{RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M},
{PERIPHS_IO_MUX_GPIO5_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_SD_CLK_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_SD_DATA0_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_SD_DATA1_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_SD_DATA2_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_SD_DATA3_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_SD_CMD_U, FUN_PU, FUN_PD},
{RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M},
{RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M},
{RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M},
{RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M},
{PERIPHS_IO_MUX_GPIO16_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO17_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO18_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO19_U, FUN_PU, FUN_PD},
{0,0,0},
{PERIPHS_IO_MUX_GPIO21_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO22_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO23_U, FUN_PU, FUN_PD},
{0,0,0},
{RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M},
{RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M},
{RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M},
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0},
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M},
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M},
{PERIPHS_IO_MUX_GPIO34_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO35_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO36_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO37_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO38_U, FUN_PU, FUN_PD},
{PERIPHS_IO_MUX_GPIO39_U, FUN_PU, FUN_PD}
};
esp_err_t gpio_pullup_en(gpio_num_t gpio_num) {
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
rtc_gpio_pullup_en(gpio_num);
}else{
REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
}
return ESP_OK;
}
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) {
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
rtc_gpio_pullup_dis(gpio_num);
}else{
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
}
return ESP_OK;
}
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) {
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
rtc_gpio_pulldown_en(gpio_num);
}else{
REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
}
return ESP_OK;
}
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num) {
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
rtc_gpio_pulldown_dis(gpio_num);
}else{
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
}
return ESP_OK;
}
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
@ -148,7 +120,7 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
esp_err_t gpio_intr_enable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if(xPortGetCoreID() == 0) {
if (xPortGetCoreID() == 0) {
GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr
} else {
GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr
@ -166,7 +138,7 @@ esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if(gpio_num < 32) {
if (gpio_num < 32) {
GPIO.enable_w1tc = (0x1 << gpio_num);
} else {
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
@ -177,7 +149,7 @@ static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
if(gpio_num < 32) {
if (gpio_num < 32) {
GPIO.enable_w1ts = (0x1 << gpio_num);
} else {
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
@ -188,14 +160,14 @@ static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if(level) {
if(gpio_num < 32) {
if (level) {
if (gpio_num < 32) {
GPIO.out_w1ts = (1 << gpio_num);
} else {
GPIO.out1_w1ts.data = (1 << (gpio_num - 32));
}
} else {
if(gpio_num < 32) {
if (gpio_num < 32) {
GPIO.out_w1tc = (1 << gpio_num);
} else {
GPIO.out1_w1tc.data = (1 << (gpio_num - 32));
@ -206,7 +178,7 @@ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
int gpio_get_level(gpio_num_t gpio_num)
{
if(gpio_num < 32) {
if (gpio_num < 32) {
return (GPIO.in >> gpio_num) & 0x1;
} else {
return (GPIO.in1.data >> (gpio_num - 32)) & 0x1;
@ -218,27 +190,27 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
switch(pull) {
case GPIO_PULLUP_ONLY:
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
break;
case GPIO_PULLDOWN_ONLY:
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
break;
case GPIO_PULLUP_PULLDOWN:
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
break;
case GPIO_FLOATING:
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
break;
default:
ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u",gpio_num,pull);
ret = ESP_ERR_INVALID_ARG;
break;
switch (pull) {
case GPIO_PULLUP_ONLY:
gpio_pulldown_dis(gpio_num);
gpio_pullup_en(gpio_num);
break;
case GPIO_PULLDOWN_ONLY:
gpio_pulldown_en(gpio_num);
gpio_pullup_dis(gpio_num);
break;
case GPIO_PULLUP_PULLDOWN:
gpio_pulldown_en(gpio_num);
gpio_pullup_en(gpio_num);
break;
case GPIO_FLOATING:
gpio_pulldown_dis(gpio_num);
gpio_pullup_dis(gpio_num);
break;
default:
ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull);
ret = ESP_ERR_INVALID_ARG;
break;
}
return ret;
}
@ -246,30 +218,30 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) {
ESP_LOGE(GPIO_TAG, "io_num=%d can only be input",gpio_num);
if (gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) {
ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
return ESP_ERR_INVALID_ARG;
}
esp_err_t ret = ESP_OK;
if(mode & GPIO_MODE_DEF_INPUT) {
if (mode & GPIO_MODE_DEF_INPUT) {
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
} else {
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
}
if(mode & GPIO_MODE_DEF_OUTPUT) {
if(gpio_num < 32) {
if (mode & GPIO_MODE_DEF_OUTPUT) {
if (gpio_num < 32) {
GPIO.enable_w1ts = (0x1 << gpio_num);
} else {
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
}
} else {
if(gpio_num < 32) {
if (gpio_num < 32) {
GPIO.enable_w1tc = (0x1 << gpio_num);
} else {
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
}
}
if(mode & GPIO_MODE_DEF_OD) {
if (mode & GPIO_MODE_DEF_OD) {
GPIO.pin[gpio_num].pad_driver = 1;
} else {
GPIO.pin[gpio_num].pad_driver = 0;
@ -287,53 +259,56 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig)
uint8_t od_en = 0;
uint8_t pu_en = 0;
uint8_t pd_en = 0;
if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) {
if (pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) {
ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error ");
return ESP_ERR_INVALID_ARG;
}
if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) {
if ((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) {
//GPIO 34/35/36/37/38/39 can only be used as input mode;
if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) {
if ((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) {
ESP_LOGE(GPIO_TAG, "GPIO34-39 can only be used as input mode");
return ESP_ERR_INVALID_ARG;
}
}
do {
io_reg = GPIO_PIN_MUX_REG[io_num];
if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) {
if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
if (((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) {
if(RTC_GPIO_IS_VALID_GPIO(io_num)){
rtc_gpio_deinit(io_num);
}
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
input_en = 1;
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]);
} else {
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]);
}
if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
od_en = 1;
GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */
} else {
GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */
}
if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
output_en = 1;
gpio_output_enable(io_num);
} else {
gpio_output_disable(io_num);
}
if(pGPIOConfig->pull_up_en) {
if (pGPIOConfig->pull_up_en) {
pu_en = 1;
REG_SET_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pu);
gpio_pullup_en(io_num);
} else {
REG_CLR_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pu);
gpio_pullup_dis(io_num);
}
if(pGPIOConfig->pull_down_en) {
if (pGPIOConfig->pull_down_en) {
pd_en = 1;
REG_SET_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd);
gpio_pulldown_en(io_num);
} else {
REG_CLR_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd);
gpio_pulldown_dis(io_num);
}
ESP_LOGI(GPIO_TAG, "GPIO[%d]| InputEn: %d| OutputEn: %d| OpenDrain: %d| Pullup: %d| Pulldown: %d| Intr:%d ", io_num, input_en, output_en, od_en, pu_en, pd_en, pGPIOConfig->intr_type);
gpio_set_intr_type(io_num, pGPIOConfig->intr_type);
if(pGPIOConfig->intr_type) {
if (pGPIOConfig->intr_type) {
gpio_intr_enable(io_num);
} else {
gpio_intr_disable(io_num);
@ -341,7 +316,7 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig)
PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */
}
io_num++;
} while(io_num < GPIO_PIN_COUNT);
} while (io_num < GPIO_PIN_COUNT);
return ESP_OK;
}
@ -360,11 +335,11 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
GPIO.pin[gpio_num].int_type = intr_type;
GPIO.pin[gpio_num].wakeup_enable = 0x1;
} else {
ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u",gpio_num);
ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u", gpio_num);
ret = ESP_ERR_INVALID_ARG;
}
return ret;

View File

@ -0,0 +1,122 @@
// 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_ADC_H_
#define _DRIVER_ADC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "esp_err.h"
typedef enum {
ADC_ATTEN_0db = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
ADC_ATTEN_2_5db = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
ADC_ATTEN_6db = 2, /*!<The input voltage of ADC will be reduced to about 1/2 */
ADC_ATTEN_11db = 3, /*!<The input voltage of ADC will be reduced to about 1/3.6*/
} adc_atten_t;
typedef enum {
ADC_WIDTH_9Bit = 0, /*!< ADC capture width is 9Bit*/
ADC_WIDTH_10Bit = 1, /*!< ADC capture width is 10Bit*/
ADC_WIDTH_11Bit = 2, /*!< ADC capture width is 11Bit*/
ADC_WIDTH_12Bit = 3, /*!< ADC capture width is 12Bit*/
} adc_bits_width_t;
typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 */
ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO38 */
ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO39 */
ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO32 */
ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO33 */
ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO34 */
ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO35 */
ADC1_CHANNEL_MAX,
} adc1_channel_t;
/**
* @brief Configuration ADC1 capture width.
*
* The configuration is in effect for all channels of ADC1
*
* @param width_bit ADC1
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
/**
* @brief Configuration ADC1 capture attenuation of channels.
*
* @param channel the ADC1 channel
* @param atten attenuation
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten);
/**
* @brief ADC1 get the value of the voltage.
*
* @param channel the ADC1 channel
*
* @return
* - -1 Parameter error
* - Other the value of ADC1 channel
*/
int adc1_get_voltage(adc1_channel_t channel);
/**
* @brief Hall Sensor output value.
* @note
* The Hall Sensor uses Channel_0 and Channel_3 of ADC1.
* So, firstly: please configure ADC1 module by calling adc1_config_width before calling hall_sensor_read.
We recommend that the WIDTH ADC1 be configured as 12Bit, because the values of hall_sensor_read are small and almost the same if WIDTH ADC1 is configured as 9Bit, 10Bit or 11Bit.
* secondly: when you use the hall sensor, please do not use Channel_0 and Channel_3 of ADC1 as
* ADC channels.
*
* @return the value of hall sensor
*/
int hall_sensor_read();
/**
*----------EXAMPLE TO USE ADC1------------ *
* @code{c}
* adc1_config_width(ADC_WIDTH_12Bit);//config adc1 width
* adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db);//config channel0 attenuation
* int val=adc1_get_voltage(ADC1_CHANNEL_0);//get the val of channel0
* @endcode
**/
/**
*----------EXAMPLE TO USE HALL SENSOR------------ *
* @code{c}
* adc1_config_width(ADC_WIDTH_12Bit);//config adc1 width
* int val=hall_sensor_read();
* @endcode
**/
#ifdef __cplusplus
}
#endif
#endif /*_DRIVER_ADC_H_*/

View File

@ -0,0 +1,57 @@
// 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_DAC_H_
#define _DRIVER_DAC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "esp_err.h"
typedef enum {
DAC_CHANNEL_1 = 1, /*!< DAC channel 1 is GPIO25 */
DAC_CHANNEL_2, /*!< DAC channel 2 is GPIO26 */
DAC_CHANNEL_MAX,
} dac_channel_t;
/**
* @brief Set Dac output voltage.
*
* Dac width is 8bit ,and the voltage max is vdd
*
* @param channel dac channel
* @param dac_value dac output value
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value);
/**
*----------EXAMPLE TO USE DAC------------ *
* @code{c}
* dac_out_voltage(DAC_CHANNEL_1,200);//the dac out voltage ≈ 200*vdd/255
* @endcode
**/
#ifdef __cplusplus
}
#endif
#endif /*_DRIVER_DAC_H_*/

View File

@ -117,32 +117,6 @@ extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT];
#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) //to decide whether it is a valid GPIO number
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode
/**
* @brief Pullup/pulldown information for a single GPIO pad
*/
typedef struct {
uint32_t reg; /*!< Register to modify to enable or disable pullups or pulldowns */
uint32_t pu; /*!< Bit to set or clear in the above register to enable or disable the pullup, respectively */
uint32_t pd; /*!< Bit to set or clear in the above register to enable or disable the pulldown, respectively */
} gpio_pu_pd_desc_t;
/**
* Per-GPIO pullup/pulldown information
* On the ESP32, some GPIOs need their pullups and pulldowns enabled and disabled in the RTC
* peripheral instead of in the GPIO peripheral. This array documents for every GPIO what bit
* to set or clear.
*
* This array is non-static, so if you need a very quick way of toggling the pull-up/downs, you can just
* do e.g. REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); inline.
*
* ToDo: Functions using the contents of this array will do a read/modify/write on GPIO as well as RTC
* registers. We may need to look into muxes/locks for other code that accesses these RTC registers when we
* write drivers for the RTC stuff.
*/
extern const gpio_pu_pd_desc_t gpio_pu_pd_desc[GPIO_PIN_COUNT];
typedef enum {
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */

View File

@ -0,0 +1,167 @@
// 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_RTC_GPIO_H_
#define _DRIVER_RTC_GPIO_H_
#include <stdint.h>
#include "esp_err.h"
#include "driver/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Pullup/pulldown information for a single GPIO pad
*/
typedef struct {
uint32_t reg; /*!< Register of Rtc Pad */
uint32_t mux; /*!< Mux seletct the Rtc pad is Digital Pad or Rtc pad */
uint32_t func; /*!< Select Rtc Pad Func */
uint32_t ie; /*!< Input Enable */
uint32_t pullup; /*!< Pullup Enable */
uint32_t pulldown; /*!< PullDown Enable */
int rtc_num; /*!< The Rtc number */
} rtc_gpio_desc_t;
typedef enum {
RTC_GPIO_MODE_INPUT_ONLY , /*!< Pad output */
RTC_GPIO_MODE_OUTPUT_ONLY, /*!< Pad input */
RTC_GPIO_MODE_INPUT_OUTUT, /*!< Pad pull output + input */
RTC_GPIO_MODE_DISABLED, /*!< Pad (output + input) disable */
} rtc_gpio_mode_t;
#define RTC_GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && rtc_gpio_desc[gpio_num].reg != 0)) //to decide whether it is a valid GPIO number
extern const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] ;
/*
* @brief Init a gpio as rtc gpio
*
* when init a pad as analog function,need to call this funciton
*
* @param gpio_num gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t rtc_gpio_init(gpio_num_t gpio_num);
/**
* @brief Init a gpio as digital gpio
*
* @param gpio_num gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num);
/**
* @brief Get the rtc io input level
*
* @param gpio_num gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - 1 High level
* - 0 Low level
*/
uint32_t rtc_gpio_get_level(gpio_num_t gpio_num);
/**
* @brief Set the rtc io output level
*
* @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_12 (12);
* @param level output level;
*
* @return
* - 1 High level
* - 0 Low level
*/
esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level);
/**
* @brief Rtc gpio set direction
*
* Configure Rtc gpio direction,such as output_only,input_only,output_and_input
*
* @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
* @param mode GPIO direction
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG GPIO error
*/
esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode);
/**
* @brief Rtc gpio pullup enable
*
* If the user needs to configure the GPIO pull ,Please call gpio_set_pull_mode.This function will be called in gpio_set_pull
*
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - True the gpio number is Rts pad
* - False the gpio number is Digital pad
*/
esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num);
/**
* @brief Rtc gpio pulldown enable
*
* If the user needs to configure the GPIO pull ,Please call gpio_set_pull_mode.This function will be called in gpio_set_pull
*
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - True the gpio number is Rts pad
* - False the gpio number is Digital pad
*/
esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num);
/**
* @brief Rtc gpio pullup clear
*
* If the user needs to configure the GPIO pull ,Please call gpio_set_pull_mode.This function will be called in gpio_set_pull
*
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - True the gpio number is Rts pad
* - False the gpio number is Digital pad
*/
esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num);
/**
* @brief Rtc gpio pulldown clear
*
* If the user needs to configure the GPIO pull ,Please call gpio_set_pull_mode.This function will be called in gpio_set_pull
*
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - True the gpio number is Rts pad
* - False the gpio number is Digital pad
*/
esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,165 @@
// 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_TOUCH_PAD_H_
#define _DRIVER_TOUCH_PAD_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_intr.h"
#include "esp_err.h"
#define TOUCH_PAD_SLEEP_CYCLE_CONFIG (0x1000)//The Time is 150Khz,the Max value is 0xffff
#define TOUCH_PAD_MEASURE_CYCLE_CONFIG (0xffff)//The Time is 8Mhz,the Max value is 0xffff
typedef enum {
TOUCH_PAD_NUM0 = 0, /*!< Touch pad channel 0 is GPIO4 */
TOUCH_PAD_NUM1, /*!< Touch pad channel 0 is GPIO0 */
TOUCH_PAD_NUM2, /*!< Touch pad channel 0 is GPIO2 */
TOUCH_PAD_NUM3, /*!< Touch pad channel 0 is GPIO15 */
TOUCH_PAD_NUM4, /*!< Touch pad channel 0 is GPIO13 */
TOUCH_PAD_NUM5, /*!< Touch pad channel 0 is GPIO12 */
TOUCH_PAD_NUM6, /*!< Touch pad channel 0 is GPIO14 */
TOUCH_PAD_NUM7, /*!< Touch pad channel 0 is GPIO27*/
TOUCH_PAD_NUM8, /*!< Touch pad channel 0 is GPIO33*/
TOUCH_PAD_NUM9, /*!< Touch pad channel 0 is GPIO32*/
TOUCH_PAD_MAX,
} touch_pad_t;
/**
* @brief Initialize touch module.
*
*This function int touch pad module ,enable touch module
*
* @return None
*
*/
void touch_pad_init();
/**
* @brief Configure touch pad interrupt threshold.
*
*
* @param[in] touch_num : config touch num
*
* @param[in] threshold : interrupt threshold ,When the touch_pad_register less than threshold,
* will trigger the touch interrupt.User can use touch_pad_read function
* to determine the threshold.
*
* @return - ESP_OK Success
* - ESP_ERR_INVALID_ARG Touch pad error
*
*/
esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold);
/**
* @brief get touch pad touch_pad_register counter.
*
*User can use this function to determine the the interrupt threshold .When you do not touch the
*pad ,read the touch_pad_read number(NumNotTouch) by the touch_pad_register.When you touch the pad ,read the touch_pad_register
*number(NumTouch) by the touch_pad_read.Normal NumNotTouch>NumTouch,so you can select a interrupt threshold.
*
* @param[in] touch_num : touch num
* @param[out] touch_value : touch output value
*
* @return - ESP_OK Success
* - ESP_ERR_INVALID_ARG Touch pad error
*
*/
esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t * touch_value);
/**
* @brief register TouchPad interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
* @note
* Users should know that which CPU is running and then pick a INUM that is not used by system.
* We can find the information of INUM and interrupt level in soc.h.
*
* @param touch_intr_num Touch interrupt number,check the info in soc.h, and please see the core-isa.h for more details
* @param fn Interrupt handler function.
*
* @note
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
*
* @param arg Parameter for handler function
*
* @return
* - ESP_OK Success ;
* - ESP_ERR_INVALID_ARG GPIO error
*/
esp_err_t touch_pad_isr_handler_register(uint32_t touch_intr_num, void(*fn)(void*), void *arg);
/**
* *************** ATTENTION ********************/
/**
*@attention
*Touch button is through the body's capacitive characteristics,
*there is a charge discharge circuit inside the. When the hands touch,
*the charge and discharge time will be slow.
*Because of the different hardware, each pad needs to be calibrated at the factory.
*We use touch_pad_read to determine factory parament.
*/
/**
*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
* @code{c}
* touch_pad_init();
* void taskA(void* arg)
* {
* for(;;){
* vtaskDelay(20/portTICK_PERIOD_MS);
* ets_printf("tocuch pad value %u\n",touch_pad_read(0));//Take the touched status and untouched status value
* }
* }
* @endcode
**/
/**
*----------EXAMPLE TO SET ISR HANDLER ----------------------
* @code{c}
* //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
* touch_pad_isr_handler_register(19,rtc_intr,NULL); //hook the isr handler for TouchPad interrupt
* @endcode
* @note
* 1. user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
* 2. do not pick the INUM that already occupied by the system.
* 3. refer to soc.h to check which INUMs that can be used.
*/
/**
*----------EXAMPLE TO USE TOUCH_PAD------------ *
* @code{c}
* touch_pad_init();//only init one time
* touch_pad_config(0,300);//set the intr threshold,use touch_pad_read to determine this threshold
* touch_pad_isr_handler_register(19,rtc_intr,NULL)
* #include "esp_attr.h"
* void IRAM_ATTR rtc_intr(void * arg)
* {
* uint32_t pad_intr = READ_PERI_REG(SARADC_SAR_TOUCH_CTRL2_REG) & 0x3ff;
* uint8_t i = 0;
* uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
* WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr);
* SET_PERI_REG_MASK(SARADC_SAR_TOUCH_CTRL2_REG, SARADC_TOUCH_MEAS_EN_CLR);
* if (rtc_intr & RTC_CNTL_TOUCH_INT_ST) {
* for (i = 0; i < TOUCH_PAD_MAX; ++i) {
* if ((pad_intr >> i) & 0x01) {
* ets_printf("touch pad intr %u\n",i);
* }
* }
* }
* }
* @endcode
**/
#ifdef __cplusplus
}
#endif
#endif/*_DRIVER_TOUCH_PAD_H_*/

View File

@ -0,0 +1,699 @@
// 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_types.h>
#include <stdlib.h>
#include <ctype.h>
#include "rom/ets_sys.h"
#include "esp_log.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "rtc_io.h"
#include "touch_pad.h"
#include "adc.h"
#include "dac.h"
#include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h"
static const char *RTC_MODULE_TAG = "RTC_MODULE";
#define RTC_MODULE_CHECK(a, str, ret_val) if (!(a)) { \
ESP_LOGE(RTC_MODULE_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
return (ret_val); \
}
#define ADC1_CHECK_FUNCTION_RET(fun_ret) if(fun_ret!=ESP_OK){\
ESP_LOGE(RTC_MODULE_TAG,"%s:%d\n",__FUNCTION__,__LINE__);\
return ESP_FAIL;\
}
portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
//Reg,Mux,Fun,IE,Up,Down,Rtc_number
const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
{RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, 11}, //0
{0, 0, 0, 0, 0, 0, -1}, //1
{RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL_M, RTC_IO_TOUCH_PAD2_FUN_SEL_S, RTC_IO_TOUCH_PAD2_FUN_IE_M, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M, 12}, //2
{0, 0, 0, 0, 0, 0, -1}, //3
{RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, RTC_IO_TOUCH_PAD0_FUN_SEL_S, RTC_IO_TOUCH_PAD0_FUN_IE_M, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M, 10}, //4
{0, 0, 0, 0, 0, 0, -1}, //5
{0, 0, 0, 0, 0, 0, -1}, //6
{0, 0, 0, 0, 0, 0, -1}, //7
{0, 0, 0, 0, 0, 0, -1}, //8
{0, 0, 0, 0, 0, 0, -1}, //9
{0, 0, 0, 0, 0, 0, -1}, //10
{0, 0, 0, 0, 0, 0, -1}, //11
{RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL_M, RTC_IO_TOUCH_PAD5_FUN_SEL_S, RTC_IO_TOUCH_PAD5_FUN_IE_M, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M, 15}, //12
{RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_MUX_SEL_M, RTC_IO_TOUCH_PAD4_FUN_SEL_S, RTC_IO_TOUCH_PAD4_FUN_IE_M, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M, 14}, //13
{RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_MUX_SEL_M, RTC_IO_TOUCH_PAD6_FUN_SEL_S, RTC_IO_TOUCH_PAD6_FUN_IE_M, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M, 16}, //14
{RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_MUX_SEL_M, RTC_IO_TOUCH_PAD3_FUN_SEL_S, RTC_IO_TOUCH_PAD3_FUN_IE_M, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M, 13}, //15
{0, 0, 0, 0, 0, 0, -1}, //16
{0, 0, 0, 0, 0, 0, -1}, //17
{0, 0, 0, 0, 0, 0, -1}, //18
{0, 0, 0, 0, 0, 0, -1}, //19
{0, 0, 0, 0, 0, 0, -1}, //20
{0, 0, 0, 0, 0, 0, -1}, //21
{0, 0, 0, 0, 0, 0, -1}, //22
{0, 0, 0, 0, 0, 0, -1}, //23
{0, 0, 0, 0, 0, 0, -1}, //24
{RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M, RTC_IO_PDAC1_FUN_SEL_S, RTC_IO_PDAC1_FUN_IE_M, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M, 6}, //25
{RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_MUX_SEL_M, RTC_IO_PDAC2_FUN_SEL_S, RTC_IO_PDAC2_FUN_IE_M, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M, 7}, //26
{RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_MUX_SEL_M, RTC_IO_TOUCH_PAD7_FUN_SEL_S, RTC_IO_TOUCH_PAD7_FUN_IE_M, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M, 17}, //27
{0, 0, 0, 0, 0, 0, -1}, //28
{0, 0, 0, 0, 0, 0, -1}, //29
{0, 0, 0, 0, 0, 0, -1}, //30
{0, 0, 0, 0, 0, 0, -1}, //31
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL_M, RTC_IO_X32P_FUN_SEL_S, RTC_IO_X32P_FUN_IE_M, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M, 9}, //32
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL_M, RTC_IO_X32N_FUN_SEL_S, RTC_IO_X32N_FUN_IE_M, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M, 8}, //33
{RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_MUX_SEL_M, RTC_IO_ADC1_FUN_SEL_S, RTC_IO_ADC1_FUN_IE_M, 0, 0, 4}, //34
{RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_MUX_SEL_M, RTC_IO_ADC2_FUN_SEL_S, RTC_IO_ADC2_FUN_IE_M, 0, 0, 5}, //35
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE1_MUX_SEL_M, RTC_IO_SENSE1_FUN_SEL_S, RTC_IO_SENSE1_FUN_IE_M, 0, 0, 0}, //36
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE2_MUX_SEL_M, RTC_IO_SENSE2_FUN_SEL_S, RTC_IO_SENSE2_FUN_IE_M, 0, 0, 1}, //37
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE3_MUX_SEL_M, RTC_IO_SENSE3_FUN_SEL_S, RTC_IO_SENSE3_FUN_IE_M, 0, 0, 2}, //38
{RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE4_MUX_SEL_M, RTC_IO_SENSE4_FUN_SEL_S, RTC_IO_SENSE4_FUN_IE_M, 0, 0, 3}, //39
};
/*---------------------------------------------------------------
RTC IO
---------------------------------------------------------------*/
esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux));
//0:RTC FUNCIOTN 1,2,3:Reserved
SET_PERI_REG_BITS(rtc_gpio_desc[gpio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0x0, rtc_gpio_desc[gpio_num].func);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Select Gpio as Digital Gpio
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux));
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t rtc_gpio_output_enable(gpio_num_t gpio_num)
{
int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;
RTC_MODULE_CHECK(rtc_gpio_num != -1, "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
SET_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TS_S)));
CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TC_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TC_S)));
return ESP_OK;
}
static esp_err_t rtc_gpio_output_disable(gpio_num_t gpio_num)
{
int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;
RTC_MODULE_CHECK(rtc_gpio_num != -1, "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TS_S)));
SET_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TC_REG, (1 << ( rtc_gpio_num + RTC_GPIO_ENABLE_W1TC_S)));
return ESP_OK;
}
static esp_err_t rtc_gpio_input_enable(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t rtc_gpio_input_disable(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
int rtc_gpio_num = rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;;
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
if (level) {
WRITE_PERI_REG(RTC_GPIO_OUT_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_OUT_DATA_W1TS_S)));
} else {
WRITE_PERI_REG(RTC_GPIO_OUT_W1TC_REG, (1 << (rtc_gpio_num + RTC_GPIO_OUT_DATA_W1TC_S)));
}
return ESP_OK;
}
uint32_t rtc_gpio_get_level(gpio_num_t gpio_num)
{
uint32_t level = 0;
int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
level = READ_PERI_REG(RTC_GPIO_IN_REG);
portEXIT_CRITICAL(&rtc_spinlock);
return ((level >> (RTC_GPIO_IN_NEXT_S + rtc_gpio_num)) & 0x01);
}
esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
switch (mode) {
case RTC_GPIO_MODE_INPUT_ONLY:
rtc_gpio_output_disable(gpio_num);
rtc_gpio_input_enable(gpio_num);
break;
case RTC_GPIO_MODE_OUTPUT_ONLY:
rtc_gpio_output_enable(gpio_num);
rtc_gpio_input_disable(gpio_num);
break;
case RTC_GPIO_MODE_INPUT_OUTUT:
rtc_gpio_output_enable(gpio_num);
rtc_gpio_input_enable(gpio_num);
break;
case RTC_GPIO_MODE_DISABLED:
rtc_gpio_output_disable(gpio_num);
rtc_gpio_input_disable(gpio_num);
break;
}
return ESP_OK;
}
esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num)
{
//this is a digital pad
if (rtc_gpio_desc[gpio_num].pullup == 0) {
return ESP_FAIL;
}
//this is a rtc pad
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num)
{
//this is a digital pad
if (rtc_gpio_desc[gpio_num].pulldown == 0) {
return ESP_FAIL;
}
//this is a rtc pad
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num)
{
//this is a digital pad
if ( rtc_gpio_desc[gpio_num].pullup == 0 ) {
return ESP_FAIL;
}
//this is a rtc pad
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num)
{
//this is a digital pad
if (rtc_gpio_desc[gpio_num].pulldown == 0) {
return ESP_FAIL;
}
//this is a rtc pad
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/*---------------------------------------------------------------
Touch Pad
---------------------------------------------------------------*/
esp_err_t touch_pad_isr_handler_register(uint32_t touch_intr_num, void(*fn)(void *), void *arg)
{
RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG);
ESP_INTR_DISABLE(touch_intr_num);
intr_matrix_set(xPortGetCoreID(), ETS_RTC_CORE_INTR_SOURCE, touch_intr_num);
xt_set_interrupt_handler(touch_intr_num, fn, arg);
ESP_INTR_ENABLE(touch_intr_num);
return ESP_OK;
}
static esp_err_t touch_pad_get_io_num(touch_pad_t touch_num, gpio_num_t *gpio_num)
{
switch (touch_num) {
case TOUCH_PAD_NUM0:
*gpio_num = 4;
break;
case TOUCH_PAD_NUM1:
*gpio_num = 0;
break;
case TOUCH_PAD_NUM2:
*gpio_num = 2;
break;
case TOUCH_PAD_NUM3:
*gpio_num = 15;
break;
case TOUCH_PAD_NUM4:
*gpio_num = 13;
break;
case TOUCH_PAD_NUM5:
*gpio_num = 12;
break;
case TOUCH_PAD_NUM6:
*gpio_num = 14;
break;
case TOUCH_PAD_NUM7:
*gpio_num = 27;
break;
case TOUCH_PAD_NUM8:
*gpio_num = 33;
break;
case TOUCH_PAD_NUM9:
*gpio_num = 32;
break;
default:
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
static esp_err_t touch_pad_init_config(uint16_t sleep_cycle, uint16_t sample_cycle_num)
{
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
//clear touch enable
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0);
//enable Rtc Touch pad Timer
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN);
//config pad module sleep time and sample num
//Touch pad SleepCycle Time = 150Khz
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_SLEEP_CYCLES, sleep_cycle, SENS_TOUCH_SLEEP_CYCLES_S);//150kHZ
//Touch Pad Measure Time= 8Mhz
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, sample_cycle_num, SENS_TOUCH_MEAS_DELAY_S); //8Mhz
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
void touch_pad_init()
{
touch_pad_init_config(TOUCH_PAD_SLEEP_CYCLE_CONFIG, TOUCH_PAD_MEASURE_CYCLE_CONFIG);
}
static void touch_pad_counter_init(touch_pad_t touch_num)
{
portENTER_CRITICAL(&rtc_spinlock);
//Enable Tie,Init Level(Counter)
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_TIE_OPT_M);
//Touch Set Slop(Counter)
SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_DAC_V, 7, RTC_IO_TOUCH_PAD0_DAC_S);
//Enable Touch Pad IO
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_START_M);
portEXIT_CRITICAL(&rtc_spinlock);
}
static void touch_pad_power_on(touch_pad_t touch_num)
{
portENTER_CRITICAL(&rtc_spinlock);
//Enable Touch Pad Power on
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_XPD_M);
portEXIT_CRITICAL(&rtc_spinlock);
}
static void toch_pad_io_init(touch_pad_t touch_num)
{
gpio_num_t gpio_num = GPIO_NUM_0;
touch_pad_get_io_num(touch_num, &gpio_num);
rtc_gpio_init(gpio_num);
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
rtc_gpio_pulldown_dis(gpio_num);
rtc_gpio_pullup_dis(gpio_num);
}
static esp_err_t touch_start(touch_pad_t touch_num)
{
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Enable Digital rtc control :work mode and out mode
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num + SENS_TOUCH_PAD_WORKEN_S)) | \
(1 << (touch_num + SENS_TOUCH_PAD_OUTEN2_S)) | \
(1 << (touch_num + SENS_TOUCH_PAD_OUTEN1_S)));
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t touch_stop(touch_pad_t touch_num)
{
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Disable Digital rtc control :work mode and out mode
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num + SENS_TOUCH_PAD_WORKEN_S)) | \
(1 << (touch_num + SENS_TOUCH_PAD_OUTEN2_S)) | \
(1 << (touch_num + SENS_TOUCH_PAD_OUTEN1_S)));
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
{
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//clear touch force ,select the Touch mode is Timer
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M);
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M);
//set threshold
uint8_t shift;
shift = (touch_num & 1) ? SENS_TOUCH_OUT_TH1_S : SENS_TOUCH_OUT_TH0_S;
SET_PERI_REG_BITS((SENS_SAR_TOUCH_THRES1_REG + (touch_num / 2) * 4), SENS_TOUCH_OUT_TH0, threshold, shift);
//When touch value < threshold ,the Intr will give
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL);
//Intr will give ,when SET0 < threshold
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_1EN);
//Enable Rtc Touch Module Intr,the Interrupt need Rtc out Enable
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);
portEXIT_CRITICAL(&rtc_spinlock);
touch_pad_power_on(touch_num);
toch_pad_io_init(touch_num);
touch_pad_counter_init(touch_num);
touch_start(touch_num);
return ESP_OK;
}
esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value)
{
RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(touch_value!=NULL, "touch_value", ESP_ERR_INVALID_ARG);
uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num)));
//Disable Intr
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num + SENS_TOUCH_PAD_OUTEN2_S)) | \
((1 << (touch_num + SENS_TOUCH_PAD_OUTEN1_S))));
toch_pad_io_init(touch_num);
touch_pad_counter_init(touch_num);
touch_pad_power_on(touch_num);
//force oneTime test start
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M);
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S);
while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {};
uint8_t shift = (touch_num & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S;
*touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (touch_num / 2) * 4) >> shift;
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
//force oneTime test end
//clear touch force ,select the Touch mode is Timer
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M);
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M);
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
/*---------------------------------------------------------------
ADC
---------------------------------------------------------------*/
static esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num)
{
RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
switch (channel) {
case ADC1_CHANNEL_0:
*gpio_num = 36;
break;
case ADC1_CHANNEL_1:
*gpio_num = 37;
break;
case ADC1_CHANNEL_2:
*gpio_num = 38;
break;
case ADC1_CHANNEL_3:
*gpio_num = 39;
break;
case ADC1_CHANNEL_4:
*gpio_num = 32;
break;
case ADC1_CHANNEL_5:
*gpio_num = 33;
break;
case ADC1_CHANNEL_6:
*gpio_num = 34;
break;
case ADC1_CHANNEL_7:
*gpio_num = 35;
break;
default:
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
static esp_err_t adc1_pad_init(adc1_channel_t channel)
{
gpio_num_t gpio_num = 0;
ADC1_CHECK_FUNCTION_RET(adc1_pad_get_io_num(channel, &gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_init(gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_output_disable(gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_input_disable(gpio_num));
ADC1_CHECK_FUNCTION_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
return ESP_OK;
}
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
{
RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(atten <= ADC_ATTEN_11db, "ADC Atten Err", ESP_ERR_INVALID_ARG);
adc1_pad_init(channel);
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, atten, (channel * 2)); //SAR1_atten
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t adc1_config_width(adc_bits_width_t width_bit)
{
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH_V, width_bit, SENS_SAR1_BIT_WIDTH_S); //SAR2_BIT_WIDTH[1:0]=0x3, SAR1_BIT_WIDTH[1:0]=0x3
//Invert the adc value,the Output value is invert
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
//Set The adc sample width,invert adc value,must
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT_V, width_bit, SENS_SAR1_SAMPLE_BIT_S); //digital sar1_bit_width[1:0]=3
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
int adc1_get_voltage(adc1_channel_t channel)
{
uint16_t adc_value;
uint8_t atten = 0;
RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Adc Controler is Rtc module,not ulp coprocessor
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_MEAS1_START_FORCE_S); //force pad mux and force start
//Bit1=0:Fsm Bit1=1(Bit0=0:PownDown Bit10=1:Powerup)
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); //force XPD_SAR=0, use XPD_FSM
//Disable Amp Bit1=0:Fsm Bit1=1(Bit0=0:PownDown Bit10=1:Powerup)
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
//Open the ADC1 Data port Not ulp coprocessor
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_SAR1_EN_PAD_FORCE_S); //open the ADC1 data port
//Select channel
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S); //pad enable
SET_PERI_REG_BITS(SENS_SAR_MEAS_CTRL_REG, 0xfff, 0x0, SENS_AMP_RST_FB_FSM_S); //[11:8]:short ref ground, [7:4]:short ref, [3:0]:rst fb
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==0
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 0, SENS_MEAS1_START_SAR_S); //start force 0
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_MEAS1_START_SAR_S); //start force 1
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0) {}; //read done
adc_value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
portEXIT_CRITICAL(&rtc_spinlock);
return adc_value;
}
/*---------------------------------------------------------------
DAC
---------------------------------------------------------------*/
static esp_err_t dac_pad_get_io_num(dac_channel_t channel, gpio_num_t *gpio_num)
{
RTC_MODULE_CHECK(channel < DAC_CHANNEL_MAX, "DAC Channel Err", ESP_ERR_INVALID_ARG);
switch (channel) {
case DAC_CHANNEL_1:
*gpio_num = 25;
break;
case DAC_CHANNEL_2:
*gpio_num = 26;
break;
default:
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
static esp_err_t dac_rtc_pad_init(dac_channel_t channel)
{
RTC_MODULE_CHECK(channel < DAC_CHANNEL_MAX, "DAC Channel Err", ESP_ERR_INVALID_ARG);
gpio_num_t gpio_num = 0;
dac_pad_get_io_num(channel, &gpio_num);
rtc_gpio_init(gpio_num);
rtc_gpio_output_disable(gpio_num);
rtc_gpio_input_disable(gpio_num);
rtc_gpio_pullup_dis(gpio_num);
rtc_gpio_pulldown_dis(gpio_num);
return ESP_OK;
}
static esp_err_t dac_out_enable(dac_channel_t channel)
{
if (channel == DAC_CHANNEL_1) {
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);
portEXIT_CRITICAL(&rtc_spinlock);
} else if (channel == DAC_CHANNEL_2) {
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);
portEXIT_CRITICAL(&rtc_spinlock);
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
static esp_err_t dac_out_disable(dac_channel_t channel)
{
if (channel == DAC_CHANNEL_1) {
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);
portEXIT_CRITICAL(&rtc_spinlock);
} else if (channel == DAC_CHANNEL_2) {
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);
portEXIT_CRITICAL(&rtc_spinlock);
} else {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value)
{
RTC_MODULE_CHECK(channel < DAC_CHANNEL_MAX, "DAC Channel Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Disable Tone
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
//Disable Channel Tone
if (channel == DAC_CHANNEL_1) {
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
} else if (channel == DAC_CHANNEL_2) {
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN2_M);
}
//Set the Dac value
if (channel == DAC_CHANNEL_1) {
SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, dac_value, RTC_IO_PDAC1_DAC_S); //dac_output
} else if (channel == DAC_CHANNEL_2) {
SET_PERI_REG_BITS(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_DAC, dac_value, RTC_IO_PDAC2_DAC_S); //dac_output
}
portEXIT_CRITICAL(&rtc_spinlock);
//dac pad init
dac_rtc_pad_init(channel);
dac_out_enable(channel);
return ESP_OK;
}
/*---------------------------------------------------------------
HALL SENSOR
---------------------------------------------------------------*/
static int hall_sensor_get_value() //hall sensor without LNA
{
int Sens_Vp0;
int Sens_Vn0;
int Sens_Vp1;
int Sens_Vn1;
int hall_value;
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_XPD_HALL_FORCE_M); // hall sens force enable
SET_PERI_REG_MASK(RTC_IO_HALL_SENS_REG, RTC_IO_XPD_HALL); // xpd hall
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_HALL_PHASE_FORCE_M); // phase force
CLEAR_PERI_REG_MASK(RTC_IO_HALL_SENS_REG, RTC_IO_HALL_PHASE); // hall phase
Sens_Vp0 = adc1_get_voltage(ADC1_CHANNEL_0);
Sens_Vn0 = adc1_get_voltage(ADC1_CHANNEL_3);
SET_PERI_REG_MASK(RTC_IO_HALL_SENS_REG, RTC_IO_HALL_PHASE);
Sens_Vp1 = adc1_get_voltage(ADC1_CHANNEL_0);
Sens_Vn1 = adc1_get_voltage(ADC1_CHANNEL_3);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_XPD_HALL_FORCE);
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_HALL_PHASE_FORCE);
portEXIT_CRITICAL(&rtc_spinlock);
hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
return hall_value;
}
int hall_sensor_read()
{
adc1_pad_init(ADC1_CHANNEL_0);
adc1_pad_init(ADC1_CHANNEL_3);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_0db);
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_0db);
return hall_sensor_get_value();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -153,7 +153,7 @@
#define DR_REG_FRC_TIMER_BASE 0x3ff47000
#define DR_REG_RTCCNTL_BASE 0x3ff48000
#define DR_REG_RTCIO_BASE 0x3ff48400
#define DR_REG_SARADC_BASE 0x3ff48800
#define DR_REG_SENS_BASE 0x3ff48800
#define DR_REG_IO_MUX_BASE 0x3ff49000
#define DR_REG_RTCMEM0_BASE 0x3ff61000
#define DR_REG_RTCMEM1_BASE 0x3ff62000

View File

@ -23,7 +23,7 @@
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/saradc_reg.h"
#include "soc/sens_reg.h"
#include "sdkconfig.h"
@ -263,8 +263,8 @@ esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* prog
esp_err_t ulp_run(uint32_t entry_point)
{
SET_PERI_REG_MASK(SARADC_SAR_START_FORCE_REG, SARADC_ULP_CP_FORCE_START_TOP_M);
SET_PERI_REG_BITS(SARADC_SAR_START_FORCE_REG, SARADC_PC_INIT_V, entry_point, SARADC_PC_INIT_S);
SET_PERI_REG_MASK(SARADC_SAR_START_FORCE_REG, SARADC_ULP_CP_START_TOP_M);
SET_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP_M);
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_PC_INIT_V, entry_point, SENS_PC_INIT_S);
SET_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP_M);
return ESP_OK;
}