This repository has been archived by the owner on Jul 27, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
analog.c
124 lines (99 loc) · 3.8 KB
/
analog.c
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
/*
* This file is part of the Pivi firmware package.
* Released under the Creative Commons ATT-NC-ShareAlire license
* http://creativecommons.org/licenses/by-nc-sa/4.0/
* Copyright (C) 2014, 2015 LESS Industries S.A.
* Author: Diego Mascialino <[email protected]>
*/
#include "analog.h"
#include "mock_signals.h"
#include "adc.h"
circuit_t * _circuit;
uint8_t v_idx = 0, i_idx = 0;
/* internal functions prototypes */
void _channel_config(ADC_t *adc, enum adcch_positive_input pin, uint8_t ch_mask,enum adc_reference adc_ref);
/* ----------------------------- */
void analog_config(circuit_t *circuit)
{
_circuit = circuit;
_channel_config(circuit->V_adc, circuit->V_pin, V_ADC_CH, circuit->V_ref);
_channel_config(circuit->I_adc, circuit->I_pin, I_ADC_CH, circuit->I_ref);
}
volatile float analog_get_V_sample(void)
{
uint16_t adc_measure;
int16_t signed_measure;
adc_start_conversion(_circuit->V_adc, V_ADC_CH);
adc_wait_for_interrupt_flag(_circuit->V_adc, V_ADC_CH);
adc_measure = adc_get_result(_circuit->V_adc, V_ADC_CH);
signed_measure = adc_measure - _circuit->V_dc_offset;
return _circuit->V_gain * (signed_measure / (float) (1<<12));
}
volatile float analog_get_I_sample(void)
{
uint16_t adc_measure;
int16_t signed_measure;
adc_start_conversion(_circuit->I_adc, I_ADC_CH);
adc_wait_for_interrupt_flag(_circuit->I_adc, I_ADC_CH);
adc_measure = adc_get_result(_circuit->I_adc, I_ADC_CH);
signed_measure = adc_measure - _circuit->I_dc_offset;
return _circuit->I_gain * (signed_measure / (float) (1<<12));
}
#define OVERSAMPLING_FACTOR 10
volatile uint16_t analog_get_V_sample_calibration(void)
{
uint32_t sum = 0;
uint16_t i;
// Sum the configured number of samples.
for (i = 0; i < (1 << OVERSAMPLING_FACTOR); i++) {
adc_start_conversion(_circuit->V_adc, V_ADC_CH);
adc_wait_for_interrupt_flag(_circuit->V_adc, V_ADC_CH);
sum += adc_get_result(_circuit->V_adc, V_ADC_CH);
}
// Compute sample mean by scaling down according to oversampling factor.
sum >>= OVERSAMPLING_FACTOR;
return (uint16_t) sum;
}
volatile uint16_t analog_get_I_sample_calibration(void)
{
uint32_t sum = 0;
uint16_t i;
// Sum the configured number of samples.
for (i = 0; i < (1 << OVERSAMPLING_FACTOR); i++) {
adc_start_conversion(_circuit->I_adc, I_ADC_CH);
adc_wait_for_interrupt_flag(_circuit->I_adc, I_ADC_CH);
sum += adc_get_result(_circuit->I_adc, I_ADC_CH);
}
// Compute sample mean by scaling down according to oversampling factor.
sum >>= OVERSAMPLING_FACTOR;
return (uint16_t) sum;
}
void _channel_config(ADC_t *adc, enum adcch_positive_input pin, uint8_t ch_mask, enum adc_reference adc_ref)
{
struct adc_config adc_conf;
struct adc_channel_config adcch_conf;
adc_read_configuration(adc, &adc_conf);
adcch_read_configuration(adc, ch_mask, &adcch_conf);
/* Configure the ADC module:
* - unsigned, 12-bit results
* - external voltage reference
* - 200 kHz maximum clock rate
* - manual conversion triggering
*/
adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, adc_ref);
adc_set_clock_rate(&adc_conf, ADC_FREQ);
adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 2, 0);
adc_write_configuration(adc, &adc_conf);
/* Configure ADC channel 0:
* - single-ended measurement from configured input pin
* - interrupt flag set on completed conversion
*/
adcch_set_input(&adcch_conf, pin, ADCCH_NEG_NONE, 1);
adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
adcch_disable_interrupt(&adcch_conf);
adcch_write_configuration(adc, ch_mask, &adcch_conf);
adc_enable(adc);
//Warm Up
adc_start_conversion(adc, ch_mask);
adc_wait_for_interrupt_flag(adc, ch_mask);
}