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
|
#include "project.h"
#define T do { printf("%s:%d\r\n",__FILE__,__LINE__); } while (0)
void adc_dump (void)
{
printf ("ADC_SR %x ADC_CR1 %x ADC_CR2 %x\r\n", (unsigned) ADC_SR (ADC1),
(unsigned) ADC_CR1 (ADC1),
(unsigned) ADC_CR2 (ADC1));
}
volatile unsigned timeout;
void adc_tick (void)
{
if (timeout) timeout--;
}
static int adc_wait (volatile uint32_t *reg, uint32_t wait_while_set, uint32_t wait_while_clear, unsigned ms)
{
timeout = MS_TO_TICKS (ms);
while ((*reg) & wait_while_set)
if (!timeout) {
printf ("QADC timeout\r\n");
return -1;
}
while ((~ (*reg)) & wait_while_clear)
if (!timeout) {
printf ("QADC timeout\r\n");
return -1;
}
return 0;
}
int adc_calibrate (void)
{
adc_off (ADC1);
adc_power_on (ADC1);
delay_ms (5);
ADC_CR2 (ADC1) |= ADC_CR2_RSTCAL;
if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_CAL, 0, 2)) return -1;
ADC_CR2 (ADC1) |= ADC_CR2_CAL;
if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_CAL, 0, 2)) return -1;
return 0;
}
unsigned adc_convert (unsigned channel)
{
uint8_t ch = channel;
adc_calibrate();
adc_set_regular_sequence (ADC1, 1, &ch);
/* Start conversion on regular channels. */
ADC_CR2 (ADC1) |= ADC_CR2_SWSTART;
if (adc_wait (&ADC_CR2 (ADC1), ADC_CR2_SWSTART, 0, 2))
return 0;
if (adc_wait (&ADC_SR (ADC1), 0, ADC_SR_EOC, 2))
return 0;
return adc_read_regular (ADC1);
}
void adc_init (void)
{
/* main set ADC clock is 9Mhz */
adc_dump();
adc_off (ADC1);
rcc_periph_clock_enable (RCC_ADC1);
#if 0
rcc_peripheral_reset (&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST);
rcc_peripheral_clear_reset (&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST);
#endif
adc_set_dual_mode (ADC_CR1_DUALMOD_IND);
adc_disable_scan_mode (ADC1);
adc_enable_temperature_sensor (ADC1);
adc_set_single_conversion_mode (ADC1);
adc_set_sample_time (ADC1, ADC_CHANNEL0, ADC_SMPR_SMP_239DOT5CYC);
adc_set_sample_time (ADC1, ADC_CHANNEL17, ADC_SMPR_SMP_239DOT5CYC); /*Want 17.1uS , which is 154 cycles */
adc_enable_external_trigger_regular (ADC1, ADC_CR2_EXTSEL_SWSTART);
adc_set_right_aligned (ADC1);
adc_dump();
adc_calibrate();
adc_dump();
}
|