Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
消极掰
arduino-esp32
提交
d8b20984
A
arduino-esp32
项目概览
消极掰
/
arduino-esp32
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
arduino-esp32
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
d8b20984
编写于
1月 20, 2020
作者:
M
Me No Dev
提交者:
GitHub
1月 20, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use IDF's ADC Driver and Add analogReadMilliVolts (#3377)
上级
3fc974f3
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
101 addition
and
167 deletion
+101
-167
cores/esp32/esp32-hal-adc.c
cores/esp32/esp32-hal-adc.c
+97
-131
cores/esp32/esp32-hal-adc.h
cores/esp32/esp32-hal-adc.h
+4
-36
未找到文件。
cores/esp32/esp32-hal-adc.c
浏览文件 @
d8b20984
...
...
@@ -22,14 +22,16 @@
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#define DEFAULT_VREF 1100
static
esp_adc_cal_characteristics_t
*
__analogCharacteristics
[
2
]
=
{
NULL
,
NULL
};
static
uint8_t
__analogAttenuation
=
3
;
//11db
static
uint8_t
__analogWidth
=
3
;
//12 bits
static
uint8_t
__analogCycles
=
8
;
static
uint8_t
__analogSamples
=
0
;
//1 sample
static
uint8_t
__analogClockDiv
=
1
;
// Width of returned answer ()
static
uint8_t
__analogReturnedWidth
=
12
;
static
uint16_t
__analogVRef
=
0
;
static
uint8_t
__analogVRefPin
=
0
;
void
__analogSetWidth
(
uint8_t
bits
){
if
(
bits
<
9
){
...
...
@@ -37,81 +39,31 @@ void __analogSetWidth(uint8_t bits){
}
else
if
(
bits
>
12
){
bits
=
12
;
}
__analogReturnedWidth
=
bits
;
__analogWidth
=
bits
-
9
;
SET_PERI_REG_BITS
(
SENS_SAR_START_FORCE_REG
,
SENS_SAR1_BIT_WIDTH
,
__analogWidth
,
SENS_SAR1_BIT_WIDTH_S
);
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL_REG
,
SENS_SAR1_SAMPLE_BIT
,
__analogWidth
,
SENS_SAR1_SAMPLE_BIT_S
);
SET_PERI_REG_BITS
(
SENS_SAR_START_FORCE_REG
,
SENS_SAR2_BIT_WIDTH
,
__analogWidth
,
SENS_SAR2_BIT_WIDTH_S
);
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL2_REG
,
SENS_SAR2_SAMPLE_BIT
,
__analogWidth
,
SENS_SAR2_SAMPLE_BIT_S
);
}
void
__analogSetCycles
(
uint8_t
cycles
){
__analogCycles
=
cycles
;
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL_REG
,
SENS_SAR1_SAMPLE_CYCLE
,
__analogCycles
,
SENS_SAR1_SAMPLE_CYCLE_S
);
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL2_REG
,
SENS_SAR2_SAMPLE_CYCLE
,
__analogCycles
,
SENS_SAR2_SAMPLE_CYCLE_S
);
}
void
__analogSetSamples
(
uint8_t
samples
){
if
(
!
samples
){
return
;
}
__analogSamples
=
samples
-
1
;
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL_REG
,
SENS_SAR1_SAMPLE_NUM
,
__analogSamples
,
SENS_SAR1_SAMPLE_NUM_S
);
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL2_REG
,
SENS_SAR2_SAMPLE_NUM
,
__analogSamples
,
SENS_SAR2_SAMPLE_NUM_S
);
adc1_config_width
(
__analogWidth
);
}
void
__analogSetClockDiv
(
uint8_t
clockDiv
){
if
(
!
clockDiv
){
return
;
clockDiv
=
1
;
}
__analogClockDiv
=
clockDiv
;
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL_REG
,
SENS_SAR1_CLK_DIV
,
__analogClockDiv
,
SENS_SAR1_CLK_DIV_S
);
SET_PERI_REG_BITS
(
SENS_SAR_READ_CTRL2_REG
,
SENS_SAR2_CLK_DIV
,
__analogClockDiv
,
SENS_SAR2_CLK_DIV_S
);
adc_set_clk_div
(
__analogClockDiv
);
}
void
__analogSetAttenuation
(
adc_attenuation_t
attenuation
)
{
__analogAttenuation
=
attenuation
&
3
;
uint32_t
att_data
=
0
;
int
i
=
10
;
while
(
i
--
){
att_data
|=
__analogAttenuation
<<
(
i
*
2
);
}
WRITE_PERI_REG
(
SENS_SAR_ATTEN1_REG
,
att_data
&
0xFFFF
);
//ADC1 has 8 channels
WRITE_PERI_REG
(
SENS_SAR_ATTEN2_REG
,
att_data
);
}
void
IRAM_ATTR
__analogInit
(){
void
__analogInit
(){
static
bool
initialized
=
false
;
if
(
initialized
){
return
;
}
__analogSetAttenuation
(
__analogAttenuation
);
__analogSetCycles
(
__analogCycles
);
__analogSetSamples
(
__analogSamples
+
1
);
//in samples
initialized
=
true
;
__analogSetClockDiv
(
__analogClockDiv
);
__analogSetWidth
(
__analogWidth
+
9
);
//in bits
SET_PERI_REG_MASK
(
SENS_SAR_READ_CTRL_REG
,
SENS_SAR1_DATA_INV
);
SET_PERI_REG_MASK
(
SENS_SAR_READ_CTRL2_REG
,
SENS_SAR2_DATA_INV
);
SET_PERI_REG_MASK
(
SENS_SAR_MEAS_START1_REG
,
SENS_MEAS1_START_FORCE_M
);
//SAR ADC1 controller (in RTC) is started by SW
SET_PERI_REG_MASK
(
SENS_SAR_MEAS_START1_REG
,
SENS_SAR1_EN_PAD_FORCE_M
);
//SAR ADC1 pad enable bitmap is controlled by SW
SET_PERI_REG_MASK
(
SENS_SAR_MEAS_START2_REG
,
SENS_MEAS2_START_FORCE_M
);
//SAR ADC2 controller (in RTC) is started by SW
SET_PERI_REG_MASK
(
SENS_SAR_MEAS_START2_REG
,
SENS_SAR2_EN_PAD_FORCE_M
);
//SAR ADC2 pad enable bitmap is controlled by SW
CLEAR_PERI_REG_MASK
(
SENS_SAR_MEAS_WAIT2_REG
,
SENS_FORCE_XPD_SAR_M
);
//force XPD_SAR=0, use XPD_FSM
SET_PERI_REG_BITS
(
SENS_SAR_MEAS_WAIT2_REG
,
SENS_FORCE_XPD_AMP
,
0x2
,
SENS_FORCE_XPD_AMP_S
);
//force XPD_AMP=0
CLEAR_PERI_REG_MASK
(
SENS_SAR_MEAS_CTRL_REG
,
0xfff
<<
SENS_AMP_RST_FB_FSM_S
);
//clear FSM
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==
initialized
=
true
;
}
void
__analogSetPinAttenuation
(
uint8_t
pin
,
adc_attenuation_t
attenuation
)
...
...
@@ -120,21 +72,20 @@ void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
if
(
channel
<
0
||
attenuation
>
3
){
return
;
}
__analogInit
();
if
(
channel
>
7
){
SET_PERI_REG_BITS
(
SENS_SAR_ATTEN2_REG
,
3
,
attenuation
,
((
channel
-
10
)
*
2
));
if
(
channel
>
9
){
adc2_config_channel_atten
(
channel
-
10
,
attenuation
);
}
else
{
SET_PERI_REG_BITS
(
SENS_SAR_ATTEN1_REG
,
3
,
attenuation
,
(
channel
*
2
)
);
adc1_config_channel_atten
(
channel
,
attenuation
);
}
__analogInit
();
}
bool
IRAM_ATTR
__adcAttachPin
(
uint8_t
pin
){
bool
__adcAttachPin
(
uint8_t
pin
){
int8_t
channel
=
digitalPinToAnalogChannel
(
pin
);
if
(
channel
<
0
){
return
false
;
//not adc pin
log_e
(
"Pin %u is not ADC pin!"
,
pin
);
return
false
;
}
int8_t
pad
=
digitalPinToTouchChannel
(
pin
);
if
(
pad
>=
0
){
uint32_t
touch
=
READ_PERI_REG
(
SENS_SAR_TOUCH_ENABLE_REG
);
...
...
@@ -151,86 +102,103 @@ bool IRAM_ATTR __adcAttachPin(uint8_t pin){
}
pinMode
(
pin
,
ANALOG
);
__analogInit
();
__analogSetPinAttenuation
(
pin
,
__analogAttenuation
);
return
true
;
}
bool
IRAM_ATTR
__adcStart
(
uint8_t
pin
){
void
__analogReadResolution
(
uint8_t
bits
)
{
if
(
!
bits
||
bits
>
16
){
return
;
}
__analogSetWidth
(
bits
);
// hadware from 9 to 12
}
uint16_t
__analogRead
(
uint8_t
pin
)
{
int8_t
channel
=
digitalPinToAnalogChannel
(
pin
);
int
value
=
0
;
esp_err_t
r
=
ESP_OK
;
if
(
channel
<
0
){
return
false
;
//not adc pin
log_e
(
"Pin %u is not ADC pin!"
,
pin
);
return
value
;
}
__adcAttachPin
(
pin
);
if
(
channel
>
9
){
channel
-=
10
;
CLEAR_PERI_REG_MASK
(
SENS_SAR_MEAS_START2_REG
,
SENS_MEAS2_START_SAR_M
);
SET_PERI_REG_BITS
(
SENS_SAR_MEAS_START2_REG
,
SENS_SAR2_EN_PAD
,
(
1
<<
channel
),
SENS_SAR2_EN_PAD_S
);
SET_PERI_REG_MASK
(
SENS_SAR_MEAS_START2_REG
,
SENS_MEAS2_START_SAR_M
);
r
=
adc2_get_raw
(
channel
,
__analogWidth
,
&
value
);
if
(
r
==
ESP_OK
)
{
return
value
;
}
else
if
(
r
==
ESP_ERR_INVALID_STATE
)
{
log_e
(
"GPIO%u: %s: ADC2 not initialized yet."
,
pin
,
esp_err_to_name
(
r
));
}
else
if
(
r
==
ESP_ERR_TIMEOUT
)
{
log_e
(
"GPIO%u: %s: ADC2 is in use by Wi-Fi."
,
pin
,
esp_err_to_name
(
r
));
}
else
{
log_e
(
"GPIO%u: %s"
,
pin
,
esp_err_to_name
(
r
));
}
}
else
{
CLEAR_PERI_REG_MASK
(
SENS_SAR_MEAS_START1_REG
,
SENS_MEAS1_START_SAR_M
);
SET_PERI_REG_BITS
(
SENS_SAR_MEAS_START1_REG
,
SENS_SAR1_EN_PAD
,
(
1
<<
channel
),
SENS_SAR1_EN_PAD_S
);
SET_PERI_REG_MASK
(
SENS_SAR_MEAS_START1_REG
,
SENS_MEAS1_START_SAR_M
);
return
adc1_get_raw
(
channel
);
}
return
tr
ue
;
return
val
ue
;
}
bool
IRAM_ATTR
__adcBusy
(
uint8_t
pin
){
int8_t
channel
=
digitalPinToAnalogChannel
(
pin
);
if
(
channel
<
0
){
return
false
;
//not adc pin
}
if
(
channel
>
7
){
return
(
GET_PERI_REG_MASK
(
SENS_SAR_MEAS_START2_REG
,
SENS_MEAS2_DONE_SAR
)
==
0
);
void
__analogSetVRefPin
(
uint8_t
pin
){
if
(
pin
<
25
||
pin
>
27
){
pin
=
0
;
}
return
(
GET_PERI_REG_MASK
(
SENS_SAR_MEAS_START1_REG
,
SENS_MEAS1_DONE_SAR
)
==
0
)
;
__analogVRefPin
=
pin
;
}
uint16_t
IRAM_ATTR
__adcEnd
(
uint8_t
pin
)
{
uint16_t
value
=
0
;
uint32_t
__analogReadMilliVolts
(
uint8_t
pin
){
int8_t
channel
=
digitalPinToAnalogChannel
(
pin
);
if
(
channel
<
0
){
return
0
;
//not adc pin
}
if
(
channel
>
7
){
while
(
GET_PERI_REG_MASK
(
SENS_SAR_MEAS_START2_REG
,
SENS_MEAS2_DONE_SAR
)
==
0
);
//wait for conversion
value
=
GET_PERI_REG_BITS2
(
SENS_SAR_MEAS_START2_REG
,
SENS_MEAS2_DATA_SAR
,
SENS_MEAS2_DATA_SAR_S
);
}
else
{
while
(
GET_PERI_REG_MASK
(
SENS_SAR_MEAS_START1_REG
,
SENS_MEAS1_DONE_SAR
)
==
0
);
//wait for conversion
value
=
GET_PERI_REG_BITS2
(
SENS_SAR_MEAS_START1_REG
,
SENS_MEAS1_DATA_SAR
,
SENS_MEAS1_DATA_SAR_S
);
}
// Shift result if necessary
uint8_t
from
=
__analogWidth
+
9
;
if
(
from
==
__analogReturnedWidth
)
{
return
value
;
log_e
(
"Pin %u is not ADC pin!"
,
pin
);
return
0
;
}
if
(
from
>
__analogReturnedWidth
)
{
return
value
>>
(
from
-
__analogReturnedWidth
);
if
(
!
__analogVRef
){
if
(
esp_adc_cal_check_efuse
(
ESP_ADC_CAL_VAL_EFUSE_TP
)
==
ESP_OK
)
{
log_d
(
"eFuse Two Point: Supported"
);
__analogVRef
=
DEFAULT_VREF
;
}
if
(
esp_adc_cal_check_efuse
(
ESP_ADC_CAL_VAL_EFUSE_VREF
)
==
ESP_OK
)
{
log_d
(
"eFuse Vref: Supported"
);
__analogVRef
=
DEFAULT_VREF
;
}
if
(
!
__analogVRef
){
__analogVRef
=
DEFAULT_VREF
;
if
(
__analogVRefPin
){
esp_adc_cal_characteristics_t
chars
;
if
(
adc2_vref_to_gpio
(
__analogVRefPin
)
==
ESP_OK
){
__analogVRef
=
__analogRead
(
__analogVRefPin
);
esp_adc_cal_characterize
(
1
,
__analogAttenuation
,
__analogWidth
,
DEFAULT_VREF
,
&
chars
);
__analogVRef
=
esp_adc_cal_raw_to_voltage
(
__analogVRef
,
&
chars
);
log_d
(
"Vref to GPIO%u: %u"
,
__analogVRefPin
,
__analogVRef
);
}
}
}
}
return
value
<<
(
__analogReturnedWidth
-
from
);
}
uint16_t
IRAM_ATTR
__analogRead
(
uint8_t
pin
)
{
if
(
!
__adcAttachPin
(
pin
)
||
!
__adcStart
(
pin
)){
return
0
;
uint8_t
unit
=
1
;
if
(
channel
>
9
){
unit
=
2
;
}
return
__adcEnd
(
pin
);
}
void
__analogReadResolution
(
uint8_t
bits
)
{
if
(
!
bits
||
bits
>
16
){
return
;
uint16_t
adc_reading
=
__analogRead
(
pin
);
if
(
__analogCharacteristics
[
unit
-
1
]
==
NULL
){
__analogCharacteristics
[
unit
-
1
]
=
calloc
(
1
,
sizeof
(
esp_adc_cal_characteristics_t
));
if
(
__analogCharacteristics
[
unit
-
1
]
==
NULL
){
return
0
;
}
esp_adc_cal_value_t
val_type
=
esp_adc_cal_characterize
(
unit
,
__analogAttenuation
,
__analogWidth
,
__analogVRef
,
__analogCharacteristics
[
unit
-
1
]);
if
(
val_type
==
ESP_ADC_CAL_VAL_EFUSE_TP
)
{
log_i
(
"ADC%u: Characterized using Two Point Value: %u
\n
"
,
unit
,
__analogCharacteristics
[
unit
-
1
]
->
vref
);
}
else
if
(
val_type
==
ESP_ADC_CAL_VAL_EFUSE_VREF
)
{
log_i
(
"ADC%u: Characterized using eFuse Vref: %u
\n
"
,
unit
,
__analogCharacteristics
[
unit
-
1
]
->
vref
);
}
else
if
(
__analogVRef
!=
DEFAULT_VREF
){
log_i
(
"ADC%u: Characterized using Vref to GPIO%u: %u
\n
"
,
unit
,
__analogVRefPin
,
__analogCharacteristics
[
unit
-
1
]
->
vref
);
}
else
{
log_i
(
"ADC%u: Characterized using Default Vref: %u
\n
"
,
unit
,
__analogCharacteristics
[
unit
-
1
]
->
vref
);
}
}
__analogSetWidth
(
bits
);
// hadware from 9 to 12
__analogReturnedWidth
=
bits
;
// software from 1 to 16
return
esp_adc_cal_raw_to_voltage
(
adc_reading
,
__analogCharacteristics
[
unit
-
1
]);
}
int
__hallRead
()
//hall sensor without LNA
...
...
@@ -260,14 +228,12 @@ int __hallRead() //hall sensor without LNA
extern
uint16_t
analogRead
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__analogRead"
)));
extern
void
analogReadResolution
(
uint8_t
bits
)
__attribute__
((
weak
,
alias
(
"__analogReadResolution"
)));
extern
void
analogSetWidth
(
uint8_t
bits
)
__attribute__
((
weak
,
alias
(
"__analogSetWidth"
)));
extern
void
analogSetCycles
(
uint8_t
cycles
)
__attribute__
((
weak
,
alias
(
"__analogSetCycles"
)));
extern
void
analogSetSamples
(
uint8_t
samples
)
__attribute__
((
weak
,
alias
(
"__analogSetSamples"
)));
extern
void
analogSetClockDiv
(
uint8_t
clockDiv
)
__attribute__
((
weak
,
alias
(
"__analogSetClockDiv"
)));
extern
void
analogSetAttenuation
(
adc_attenuation_t
attenuation
)
__attribute__
((
weak
,
alias
(
"__analogSetAttenuation"
)));
extern
void
analogSetPinAttenuation
(
uint8_t
pin
,
adc_attenuation_t
attenuation
)
__attribute__
((
weak
,
alias
(
"__analogSetPinAttenuation"
)));
extern
int
hallRead
()
__attribute__
((
weak
,
alias
(
"__hallRead"
)));
extern
bool
adcAttachPin
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__adcAttachPin"
)));
extern
bool
adcStart
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__adcStart"
)));
extern
bool
adcBusy
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__adcBusy
"
)));
extern
uint
16_t
adcEnd
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__adcEnd
"
)));
extern
void
analogSetVRefPin
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__analogSetVRefPin
"
)));
extern
uint
32_t
analogReadMilliVolts
(
uint8_t
pin
)
__attribute__
((
weak
,
alias
(
"__analogReadMilliVolts
"
)));
cores/esp32/esp32-hal-adc.h
浏览文件 @
d8b20984
...
...
@@ -54,24 +54,6 @@ void analogReadResolution(uint8_t bits);
* */
void
analogSetWidth
(
uint8_t
bits
);
/*
* Set number of cycles per sample
* Default is 8 and seems to do well
* Range is 1 - 255
* */
void
analogSetCycles
(
uint8_t
cycles
);
/*
* Set number of samples in the range.
* Default is 1
* Range is 1 - 255
* This setting splits the range into
* "samples" pieces, which could look
* like the sensitivity has been multiplied
* that many times
* */
void
analogSetSamples
(
uint8_t
samples
);
/*
* Set the divider for the ADC clock.
* Default is 1
...
...
@@ -97,34 +79,20 @@ void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
* */
int
hallRead
();
/*
* Non-Blocking API (almost)
*
* Note: ADC conversion can run only for single pin at a time.
* That means that if you want to run ADC on two pins on the same bus,
* you need to run them one after another. Probably the best use would be
* to start conversion on both buses in parallel.
* */
/*
* Attach pin to ADC (will also clear any other analog mode that could be on)
* */
bool
adcAttachPin
(
uint8_t
pin
);
/*
* Start ADC conversion on attached pin's bus
* */
bool
adcStart
(
uint8_t
pin
);
/*
* Check if conversion on the pin's ADC bus is currently running
* Set pin to use for ADC calibration if the esp is not already calibrated (25, 26 or 27)
* */
bool
adcBusy
(
uint8_t
pin
);
void
analogSetVRefPin
(
uint8_t
pin
);
/*
* Get
the result of the conversion (will wait if it have not finished)
* Get
MilliVolts value for pin
* */
uint
16_t
adcEnd
(
uint8_t
pin
);
uint
32_t
analogReadMilliVolts
(
uint8_t
pin
);
#ifdef __cplusplus
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录