-
Notifications
You must be signed in to change notification settings - Fork 7.1k
/
adc_ll.h
1184 lines (1104 loc) · 41.1 KB
/
adc_ll.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "hal/misc.h"
#include "soc/adc_periph.h"
#include "hal/adc_types.h"
#include "hal/adc_types_private.h"
#include "hal/assert.h"
#include "soc/apb_saradc_struct.h"
#include "soc/sens_struct.h"
#include "soc/sens_reg.h"
#include "soc/apb_saradc_reg.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/regi2c_defs.h"
#include "soc/clk_tree_defs.h"
#include "hal/regi2c_ctrl.h"
#include "soc/regi2c_saradc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ADC_LL_EVENT_ADC1_ONESHOT_DONE (1 << 0)
#define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1)
/*---------------------------------------------------------------
Oneshot
---------------------------------------------------------------*/
#define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
#define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1)
/*---------------------------------------------------------------
DMA
---------------------------------------------------------------*/
#define ADC_LL_DIGI_DATA_INVERT_DEFAULT(PERIPH_NUM) (0)
#define ADC_LL_FSM_RSTB_WAIT_DEFAULT (8)
#define ADC_LL_FSM_START_WAIT_DEFAULT (5)
#define ADC_LL_FSM_STANDBY_WAIT_DEFAULT (100)
#define ADC_LL_SAMPLE_CYCLE_DEFAULT (3)
#define ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT (2)
#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15
#define ADC_LL_CLKM_DIV_B_DEFAULT 1
#define ADC_LL_CLKM_DIV_A_DEFAULT 0
#define ADC_LL_DEFAULT_CONV_LIMIT_EN 0
#define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10
/*---------------------------------------------------------------
PWDET (Power Detect)
---------------------------------------------------------------*/
#define ADC_LL_PWDET_CCT_DEFAULT (4)
typedef enum {
ADC_LL_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */
ADC_LL_POWER_SW_ON, /*!< ADC XPD controlled by SW. power on. Used for DMA mode */
ADC_LL_POWER_SW_OFF, /*!< ADC XPD controlled by SW. power off. */
} adc_ll_power_t;
typedef enum {
ADC_LL_RTC_DATA_OK = 0,
ADC_LL_RTC_CTRL_UNSELECTED = 1,
ADC_LL_RTC_CTRL_BREAK = 2,
ADC_LL_RTC_DATA_FAIL = -1,
} adc_ll_rtc_raw_data_t;
typedef enum {
ADC_LL_CTRL_RTC = 0, ///< For ADC1. Select RTC controller.
ADC_LL_CTRL_ULP = 1, ///< For ADC1 and ADC2. Select ULP controller.
ADC_LL_CTRL_DIG = 2, ///< For ADC1. Select DIG controller.
ADC_LL_CTRL_ARB = 3, ///< For ADC2. The controller is selected by the arbiter.
} adc_ll_controller_t;
/**
* @brief ADC digital controller (DMA mode) work mode.
*
* @note The conversion mode affects the sampling frequency:
* SINGLE_UNIT_1: When the measurement is triggered, only ADC1 is sampled once.
* SINGLE_UNIT_2: When the measurement is triggered, only ADC2 is sampled once.
* BOTH_UNIT : When the measurement is triggered, ADC1 and ADC2 are sampled at the same time.
* ALTER_UNIT : When the measurement is triggered, ADC1 or ADC2 samples alternately.
*/
typedef enum {
ADC_LL_DIGI_CONV_ONLY_ADC1 = 0, // Only use ADC1 for conversion
ADC_LL_DIGI_CONV_ONLY_ADC2 = 1, // Only use ADC2 for conversion
ADC_LL_DIGI_CONV_BOTH_UNIT = 2, // Use Both ADC1 and ADC2 for conversion simultaneously
ADC_LL_DIGI_CONV_ALTER_UNIT = 3 // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 .....
} adc_ll_digi_convert_mode_t;
typedef struct {
union {
struct {
uint8_t atten: 2;
uint8_t reserved: 2;
uint8_t channel: 4;
};
uint8_t val;
};
} __attribute__((packed)) adc_ll_digi_pattern_table_t;
/**
* @brief Analyze whether the obtained raw data is correct.
* ADC2 use arbiter by default. The arbitration result can be judged by the flag bit in the original data.
*
*/
typedef struct {
union {
struct {
uint16_t data: 13; /*!<ADC real output data info. Resolution: 13 bit. */
uint16_t reserved: 1; /*!<reserved */
uint16_t flag: 2; /*!<ADC data flag info.
If (flag == 0), The data is valid.
If (flag > 0), The data is invalid. */
};
uint16_t val;
};
} adc_ll_rtc_output_data_t;
/*---------------------------------------------------------------
Digital controller setting
---------------------------------------------------------------*/
/**
* Set adc fsm interval parameter for digital controller. These values are fixed for same platforms.
*
* @param rst_wait cycles between DIG ADC controller reset ADC sensor and start ADC sensor.
* @param start_wait Delay time after open xpd.
* @param standby_wait Delay time to close xpd.
*/
static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wait, uint32_t standby_wait)
{
// Internal FSM reset wait time
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.fsm_wait, rstb_wait, rst_wait);
// Internal FSM start wait time
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.fsm_wait, xpd_wait, start_wait);
// Internal FSM standby wait time
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.fsm_wait, standby_wait, standby_wait);
}
/**
* Set adc sample cycle.
*
* @note Normally, please use default value.
* @param sample_cycle The number of ADC sampling cycles. Range: 1 ~ 7.
*/
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
{
/* Should be called before writing I2C registers. */
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M);
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle);
}
/**
* Set SAR ADC module clock division factor.
* SAR ADC clock divided from digital controller clock.
*
* @param div Division factor.
*/
static inline void adc_ll_digi_set_clk_div(uint32_t div)
{
/* ADC clock divided from digital controller clock clk */
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl, sar_clk_div, div);
}
/**
* Set adc max conversion number for digital controller.
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
*
* @param meas_num Max conversion number. Range: 0 ~ 255.
*/
static inline void adc_ll_digi_set_convert_limit_num(uint32_t meas_num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.ctrl2, max_meas_num, meas_num);
}
/**
* Enable max conversion number detection for digital controller.
* If the number of ADC conversion is equal to the maximum, the conversion is stopped.
*
* @param enable true: enable; false: disable
*/
static inline void adc_ll_digi_convert_limit_enable(bool enable)
{
APB_SARADC.ctrl2.meas_num_limit = enable;
}
/**
* Set adc conversion mode for digital controller.
*
* @param mode Conversion mode select.
* TODO IDF-3610
*/
static inline void adc_ll_digi_set_convert_mode(adc_ll_digi_convert_mode_t mode)
{
if (mode == ADC_LL_DIGI_CONV_ONLY_ADC1) {
APB_SARADC.ctrl.work_mode = 0;
APB_SARADC.ctrl.sar_sel = 0;
APB_SARADC.ctrl.data_sar_sel = 0;
} else if (mode == ADC_LL_DIGI_CONV_ONLY_ADC2) {
APB_SARADC.ctrl.work_mode = 0;
APB_SARADC.ctrl.sar_sel = 1;
APB_SARADC.ctrl.data_sar_sel = 0;
} else if (mode == ADC_LL_DIGI_CONV_BOTH_UNIT) {
APB_SARADC.ctrl.work_mode = 1;
APB_SARADC.ctrl.data_sar_sel = 1;
} else if (mode == ADC_LL_DIGI_CONV_ALTER_UNIT) {
APB_SARADC.ctrl.work_mode = 2;
APB_SARADC.ctrl.data_sar_sel = 1;
}
}
/**
* Set pattern table length for digital controller.
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
* pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself.
*
* @param adc_n ADC unit.
* @param patt_len Items range: 1 ~ 16.
*/
static inline void adc_ll_digi_set_pattern_table_len(adc_unit_t adc_n, uint32_t patt_len)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.ctrl.sar1_patt_len = patt_len - 1;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.ctrl.sar2_patt_len = patt_len - 1;
}
}
/**
* Set pattern table for digital controller.
* The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
* resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
* pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself.
*
* @param adc_n ADC unit.
* @param pattern_index Items index. Range: 0 ~ 15.
* @param pattern Stored conversion rules.
*/
static inline void adc_ll_digi_set_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_config_t table)
{
uint32_t tab;
uint8_t index = pattern_index / 4;
uint8_t offset = (pattern_index % 4) * 8;
adc_ll_digi_pattern_table_t pattern = {0};
pattern.val = (table.atten & 0x3) | ((table.channel & 0xF) << 4);
if (table.unit == ADC_UNIT_1) {
tab = APB_SARADC.sar1_patt_tab[index]; // Read old register value
tab &= (~(0xFF000000 >> offset)); // clear old data
tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
APB_SARADC.sar1_patt_tab[index] = tab; // Write back
} else { // adc_n == ADC_UNIT_2
tab = APB_SARADC.sar2_patt_tab[index]; // Read old register value
tab &= (~(0xFF000000 >> offset)); // clear old data
tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
APB_SARADC.sar2_patt_tab[index] = tab; // Write back
}
}
/**
* Reset the pattern table pointer, then take the measurement rule from table header in next measurement.
*
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_clear_pattern_table(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.ctrl.sar1_patt_p_clear = 1;
APB_SARADC.ctrl.sar1_patt_p_clear = 0;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.ctrl.sar2_patt_p_clear = 1;
APB_SARADC.ctrl.sar2_patt_p_clear = 0;
}
}
/**
* Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize.
*
* @note Only ADC2 have arbiter function.
* @param cycle range: 0 ~ 4.
*/
static inline void adc_ll_digi_set_arbiter_stable_cycle(uint32_t cycle)
{
APB_SARADC.ctrl.wait_arb_cycle = cycle;
}
/**
* ADC Digital controller output data invert or not.
*
* @param adc_n ADC unit.
* @param inv_en data invert or not.
*/
static inline void adc_ll_digi_output_invert(adc_unit_t adc_n, bool inv_en)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_UNIT_2
APB_SARADC.ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert
}
}
/**
* Set the interval clock cycle for the digital controller to trigger the measurement.
* Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval.
*
* @note The trigger interval should be larger than the sampling time of the SAR ADC.
* @param cycle The clock cycle (trigger interval) of the measurement. Range: 40 ~ 4095.
*/
static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle)
{
APB_SARADC.ctrl2.timer_target = cycle;
}
/**
* Enable digital controller timer to trigger the measurement.
*/
static inline void adc_ll_digi_trigger_enable(void)
{
APB_SARADC.ctrl2.timer_sel = 1;
APB_SARADC.ctrl2.timer_en = 1;
}
/**
* Disable digital controller timer to trigger the measurement.
*/
static inline void adc_ll_digi_trigger_disable(void)
{
APB_SARADC.ctrl2.timer_en = 0;
APB_SARADC.ctrl2.timer_sel = 0;
}
/**
* Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock.
* Expression: controller_clk = (`APLL` or `APB`) / (div_num + div_a / div_b + 1).
*
* @param div_num Division factor. Range: 0 ~ 255.
* @param div_b Division factor. Range: 1 ~ 63.
* @param div_a Division factor. Range: 0 ~ 63.
*/
static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.apb_adc_clkm_conf, clkm_div_num, div_num);
APB_SARADC.apb_adc_clkm_conf.clkm_div_b = div_b;
APB_SARADC.apb_adc_clkm_conf.clkm_div_a = div_a;
}
/**
* Enable clock and select clock source for ADC digital controller.
*
* @param clk_src clock source for ADC digital controller.
*/
static inline void adc_ll_digi_clk_sel(adc_continuous_clk_src_t clk_src)
{
APB_SARADC.apb_adc_clkm_conf.clk_sel = (clk_src == ADC_DIGI_CLK_SRC_APLL) ? 1 : 2;
APB_SARADC.ctrl.sar_clk_gated = 1;
}
/**
* Disable clock for ADC digital controller.
*/
static inline void adc_ll_digi_controller_clk_disable(void)
{
APB_SARADC.ctrl.sar_clk_gated = 0;
APB_SARADC.apb_adc_clkm_conf.clk_sel = 0;
}
/**
* Reset adc digital controller filter.
*
* @param idx Filter index
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_filter_reset(adc_digi_iir_filter_t idx, adc_unit_t adc_n)
{
(void)idx;
if (adc_n == ADC_UNIT_1) {
APB_SARADC.filter_ctrl.adc1_filter_reset = 1;
APB_SARADC.filter_ctrl.adc1_filter_reset = 0;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.filter_ctrl.adc2_filter_reset = 1;
APB_SARADC.filter_ctrl.adc2_filter_reset = 0;
}
}
/**
* Set adc digital controller filter coeff.
*
* @param idx filter index
* @param adc_n adc unit
* @param channel adc channel
* @param coeff filter coeff
*/
static inline void adc_ll_digi_filter_set_factor(adc_digi_iir_filter_t idx, adc_unit_t adc_n, adc_channel_t channel, adc_digi_iir_filter_coeff_t coeff)
{
(void)idx;
(void)channel;
int mode = 0;
switch (coeff) {
case ADC_DIGI_IIR_FILTER_COEFF_2: mode = 2; break;
case ADC_DIGI_IIR_FILTER_COEFF_4: mode = 4; break;
case ADC_DIGI_IIR_FILTER_COEFF_8: mode = 8; break;
case ADC_DIGI_IIR_FILTER_COEFF_16: mode = 16; break;
case ADC_DIGI_IIR_FILTER_COEFF_64: mode = 64; break;
default: mode = 8; break;
}
if (adc_n == ADC_UNIT_1) {
APB_SARADC.filter_ctrl.adc1_filter_factor = mode;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.filter_ctrl.adc2_filter_factor = mode;
}
}
/**
* Enable/disable adc digital controller filter.
* Filtering the ADC data to obtain smooth data at higher sampling rates.
*
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
* @param idx Filter index
* @param adc_n ADC unit
* @param enable Enable / Disable
*/
static inline void adc_ll_digi_filter_enable(adc_digi_iir_filter_t idx, adc_unit_t adc_n, bool enable)
{
(void)idx;
if (adc_n == ADC_UNIT_1) {
APB_SARADC.filter_ctrl.adc1_filter_en = enable;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.filter_ctrl.adc2_filter_en = enable;
}
}
/**
* Get the filtered data of adc digital controller filter.
* The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
*
* @note The filter will filter all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @return Filtered data.
*/
static inline uint32_t adc_ll_digi_filter_read_data(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
return HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.filter_status, adc1_filter_data);
} else { // adc_n == ADC_UNIT_2
return HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.filter_status, adc2_filter_data);
}
}
/**
* Set monitor mode of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @param is_larger true: If ADC_OUT > threshold, Generates monitor interrupt.
* false: If ADC_OUT < threshold, Generates monitor interrupt.
*/
static inline void adc_ll_digi_monitor_set_mode(adc_unit_t adc_n, bool is_larger)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.thres_ctrl.adc1_thres_mode = is_larger;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.thres_ctrl.adc2_thres_mode = is_larger;
}
}
/**
* Set monitor threshold of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
* @param threshold Monitor threshold.
*/
static inline void adc_ll_digi_monitor_set_thres(adc_unit_t adc_n, uint32_t threshold)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.thres_ctrl.adc1_thres = threshold;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.thres_ctrl.adc2_thres = threshold;
}
}
/**
* Enable/disable monitor of adc digital controller.
*
* @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time.
* @param adc_n ADC unit.
*/
static inline void adc_ll_digi_monitor_enable(adc_unit_t adc_n, bool enable)
{
if (adc_n == ADC_UNIT_1) {
APB_SARADC.thres_ctrl.adc1_thres_en = enable;
} else { // adc_n == ADC_UNIT_2
APB_SARADC.thres_ctrl.adc2_thres_en = enable;
}
}
/**
* Set DMA eof num of adc digital controller.
* If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated.
*
* @param num eof num of DMA.
*/
static inline void adc_ll_digi_dma_set_eof_num(uint32_t num)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num, num);
}
/**
* Enable output data to DMA from adc digital controller.
*/
static inline void adc_ll_digi_dma_enable(void)
{
APB_SARADC.dma_conf.apb_adc_trans = 1;
}
/**
* Disable output data to DMA from adc digital controller.
*/
static inline void adc_ll_digi_dma_disable(void)
{
APB_SARADC.dma_conf.apb_adc_trans = 0;
}
/**
* Reset adc digital controller.
*/
static inline void adc_ll_digi_reset(void)
{
APB_SARADC.dma_conf.apb_adc_reset_fsm = 1;
APB_SARADC.dma_conf.apb_adc_reset_fsm = 0;
}
/*---------------------------------------------------------------
PWDET(Power detect) controller setting
---------------------------------------------------------------*/
/**
* Set adc cct for PWDET controller.
*
* @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
* @param cct Range: 0 ~ 7.
*/
static inline void adc_ll_pwdet_set_cct(uint32_t cct)
{
/* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
SENS.sar_meas2_mux.sar2_pwdet_cct = cct;
}
/**
* Get adc cct for PWDET controller.
*
* @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY.
* @return cct Range: 0 ~ 7.
*/
static inline uint32_t adc_ll_pwdet_get_cct(void)
{
/* Capacitor tuning of the PA power monitor. cct set to the same value with PHY. */
return SENS.sar_meas2_mux.sar2_pwdet_cct;
}
/*---------------------------------------------------------------
RTC controller setting
---------------------------------------------------------------*/
/**
* ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`.
*
* @param div Division factor.
*/
static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div)
{
if (adc_n == ADC_UNIT_1) {
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_reader1_ctrl, sar1_clk_div, div);
} else { // adc_n == ADC_UNIT_2
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_reader2_ctrl, sar2_clk_div, div);
}
}
/**
* Set adc output data format for RTC controller.
*
* @note ESP32S2 RTC controller only support 13bit.
* @prarm adc_n ADC unit.
* @prarm bits Output data bits width option.
*/
static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits)
{
//ESP32S2 only supports 13bit, leave here for compatibility
HAL_ASSERT(bits == ADC_BITWIDTH_13 || bits == ADC_BITWIDTH_DEFAULT);
}
/**
* Enable adc channel to start convert.
*
* @note Only one channel can be selected for once measurement.
*
* @param adc_n ADC unit.
* @param channel ADC channel number for each ADCn.
*/
static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, int channel)
{
if (adc_n == ADC_UNIT_1) {
SENS.sar_meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected.
} else { // adc_n == ADC_UNIT_2
SENS.sar_meas2_ctrl2.sar2_en_pad = (1 << channel); //only one channel is selected.
}
}
/**
* Disable adc channel to start convert.
*
* @note Only one channel can be selected in once measurement.
*
* @param adc_n ADC unit.
* @param channel ADC channel number for each ADCn.
*/
static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected.
} else { // adc_n == ADC_UNIT_2
SENS.sar_meas2_ctrl2.sar2_en_pad = 0; //only one channel is selected.
}
}
/**
* Start conversion once by software for RTC controller.
*
* @note It may be block to wait conversion idle for ADC1.
*
* @param adc_n ADC unit.
*/
static inline void adc_oneshot_ll_start(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
while (HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_slave_addr1, meas_status) != 0) {}
SENS.sar_meas1_ctrl2.meas1_start_sar = 0;
SENS.sar_meas1_ctrl2.meas1_start_sar = 1;
} else { // adc_n == ADC_UNIT_2
SENS.sar_meas2_ctrl2.meas2_start_sar = 0; //start force 0
SENS.sar_meas2_ctrl2.meas2_start_sar = 1; //start force 1
}
}
/**
* Clear the event for each ADCn for Oneshot mode
*
* @param event ADC event
*/
static inline void adc_oneshot_ll_clear_event(uint32_t event)
{
//For compatibility
}
/**
* Check the event for each ADCn for Oneshot mode
*
* @param event ADC event
*
* @return
* -true : The conversion process is finish.
* -false : The conversion process is not finish.
*/
static inline bool adc_oneshot_ll_get_event(uint32_t event)
{
bool ret = true;
if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) {
ret = (bool)SENS.sar_meas1_ctrl2.meas1_done_sar;
} else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) {
ret = (bool)SENS.sar_meas2_ctrl2.meas2_done_sar;
} else {
HAL_ASSERT(false);
}
return ret;
}
/**
* Get the converted value for each ADCn for RTC controller.
*
* @param adc_n ADC unit.
* @return
* - Converted value.
*/
static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n)
{
uint32_t ret_val = 0;
if (adc_n == ADC_UNIT_1) {
ret_val = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_meas1_ctrl2, meas1_data_sar);
} else { // adc_n == ADC_UNIT_2
ret_val = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_meas2_ctrl2, meas2_data_sar);
}
return ret_val;
}
/**
* Analyze whether the obtained raw data is correct.
* ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data.
*
* @param adc_n ADC unit.
* @param raw ADC raw data input (convert value).
* @return
* - true: raw data is valid
* - false: raw data is invalid
*/
static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw)
{
if (adc_n == ADC_UNIT_1) {
return true;
}
adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw;
if (temp->flag == 0) {
return true;
} else {
//Could be ADC_LL_RTC_CTRL_UNSELECTED, ADC_LL_RTC_CTRL_BREAK or ADC_LL_RTC_DATA_FAIL
return false;
}
}
/**
* ADC module RTC output data invert or not.
*
* @param adc_n ADC unit.
* @param inv_en data invert or not.
*/
static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en)
{
if (adc_n == ADC_UNIT_1) {
SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert
} else { // adc_n == ADC_UNIT_2
SENS.sar_reader2_ctrl.sar2_data_inv = inv_en; // Enable / Disable ADC data invert
}
}
/**
* Enable ADCn conversion complete interrupt for RTC controller.
*
* @param adc_n ADC unit.
*/
static inline void adc_ll_rtc_intr_enable(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
SENS.sar_reader1_ctrl.sar1_int_en = 1;
RTCCNTL.int_ena.rtc_saradc1 = 1;
} else { // adc_n == ADC_UNIT_2
SENS.sar_reader2_ctrl.sar2_int_en = 1;
RTCCNTL.int_ena.rtc_saradc2 = 1;
}
}
/**
* Disable ADCn conversion complete interrupt for RTC controller.
*
* @param adc_n ADC unit.
*/
static inline void adc_ll_rtc_intr_disable(adc_unit_t adc_n)
{
if (adc_n == ADC_UNIT_1) {
SENS.sar_reader1_ctrl.sar1_int_en = 0;
RTCCNTL.int_ena.rtc_saradc1 = 0;
} else { // adc_n == ADC_UNIT_2
SENS.sar_reader2_ctrl.sar2_int_en = 0;
RTCCNTL.int_ena.rtc_saradc2 = 0;
}
}
/**
* Reset RTC controller FSM.
*/
static inline void adc_ll_rtc_reset(void)
{
SENS.sar_meas1_ctrl1.rtc_saradc_reset = 1;
SENS.sar_meas1_ctrl1.rtc_saradc_reset = 0;
}
/**
* Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize.
*
* @note Only ADC2 have arbiter function.
* @param cycle range: [0,4].
*/
static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle)
{
SENS.sar_reader2_ctrl.sar2_wait_arb_cycle = cycle;
}
/**
* Set the attenuation of a particular channel on ADCn.
*
* @note For any given channel, this function must be called before the first time conversion.
*
* The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage,
* usually 3.3V) requires setting >0dB signal attenuation for that ADC channel.
*
* When VDD_A is 3.3V:
*
* - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
* - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
* - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
* - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
*
* @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured
* bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
*
* @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
*
* Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges:
*
* - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV
* - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV
* - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV
* - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV
*
* For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges.
*
* @param adc_n ADC unit.
* @param channel ADCn channel number.
* @param atten The attenuation option.
*/
static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten)
{
if (adc_n == ADC_UNIT_1) {
SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2));
} else { // adc_n == ADC_UNIT_2
SENS.sar_atten2 = ( SENS.sar_atten2 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2));
}
}
/**
* Get the attenuation of a particular channel on ADCn.
*
* @param adc_n ADC unit.
* @param channel ADCn channel number.
* @return atten The attenuation option.
*/
__attribute__((always_inline))
static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t channel)
{
if (adc_n == ADC_UNIT_1) {
return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3);
} else {
return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3);
}
}
/**
* Enable oneshot conversion trigger
*
* @param adc_n Not used, for compatibility
*/
static inline void adc_oneshot_ll_enable(adc_unit_t adc_n)
{
(void)adc_n;
//For compatibility
}
/**
* Disable oneshot conversion trigger for all the ADC units
*/
static inline void adc_oneshot_ll_disable_all_unit(void)
{
//For compatibility
}
/*---------------------------------------------------------------
Common setting
---------------------------------------------------------------*/
/**
* Set ADC module power management.
*
* @param manage Set ADC power status.
*/
__attribute__((always_inline))
static inline void adc_ll_digi_set_power_manage(adc_ll_power_t manage)
{
if (manage == ADC_LL_POWER_SW_ON) {
APB_SARADC.ctrl.sar_clk_gated = 1;
APB_SARADC.ctrl.xpd_sar_force = 0x3;
} else if (manage == ADC_LL_POWER_BY_FSM) {
APB_SARADC.ctrl.sar_clk_gated = 1;
APB_SARADC.ctrl.xpd_sar_force = 0x0;
} else if (manage == ADC_LL_POWER_SW_OFF) {
APB_SARADC.ctrl.sar_clk_gated = 0;
APB_SARADC.ctrl.xpd_sar_force = 0x2;
}
}
/**
* Set ADC module controller.
* There are five SAR ADC controllers:
* Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes;
* Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep;
* the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2.
*
* @param adc_n ADC unit.
* @param ctrl ADC controller.
*/
__attribute__((always_inline))
static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t ctrl)
{
if (adc_n == ADC_UNIT_1) {
switch (ctrl) {
case ADC_LL_CTRL_RTC:
SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_ULP:
SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_DIG:
SENS.sar_meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control.
SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
default:
break;
}
} else { // adc_n == ADC_UNIT_2
switch (ctrl) {
//If ADC2 is not controlled by ULP, the arbiter will decide which controller to use ADC2.
case ADC_LL_CTRL_ARB:
SENS.sar_meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
case ADC_LL_CTRL_ULP:
SENS.sar_meas2_ctrl2.meas2_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start.
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map;
break;
default:
break;
}
}
}
/**
* Set ADC2 module arbiter work mode.
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
* the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data.
*
* @note Only ADC2 support arbiter.
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
*
* @param mode Refer to ``adc_arbiter_mode_t``.
*/
__attribute__((always_inline))
static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode)
{
SENS.sar_meas2_mux.sar2_rtc_force = 0; // Enable arbiter in wakeup mode
if (mode == ADC_ARB_MODE_FIX) {
APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1;
} else if (mode == ADC_ARB_MODE_LOOP) {
APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 0;
} else {
APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 1; // Shield arbiter.
}
}
/**
* Set ADC2 module controller priority in arbiter.
* The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority,
* the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data.
*
* @note Only ADC2 support arbiter.
* @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode.
* @note Default priority: Wi-Fi(2) > RTC(1) > Digital(0);
*
* @param pri_rtc RTC controller priority. Range: 0 ~ 2.
* @param pri_dig Digital controller priority. Range: 0 ~ 2.
* @param pri_pwdet Wi-Fi controller priority. Range: 0 ~ 2.
*/
__attribute__((always_inline))
static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig, uint8_t pri_pwdet)
{
if (pri_rtc != pri_dig && pri_rtc != pri_pwdet && pri_dig != pri_pwdet) {
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_priority = pri_rtc;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_priority = pri_dig;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_priority = pri_pwdet;
}
/* Should select highest priority controller. */
if (pri_rtc > pri_dig) {
if (pri_rtc > pri_pwdet) {
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 1;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0;
} else {
APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0;
APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1;