forked from sensorium/Mozzi
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMozziGuts_impl_RENESAS_ADC.hpp
121 lines (107 loc) · 3.7 KB
/
MozziGuts_impl_RENESAS_ADC.hpp
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
/*
Parts of this file are drawn from Arduino's source code for analogRead() (https://github.com/arduino/ArduinoCore-renesas/blob/main/cores/arduino/analog.cpp) and part from Renesas' documentation (https://renesas.github.io/fsp/group___a_d_c.html), among other things.
It contains functions to interact with the ADC in order to implement async ADC reads, aka mozziAnalogRead().
*/
#include <analog.h>
//#include <analog.cpp>
#include <IRQManager.h>
/** VERBATIM from Arduino's analog.cpp
*/
#define MAX_ADC_CHANNELS 29
static uint16_t analog_values_by_channels[MAX_ADC_CHANNELS] = {0};
static void ADC_irq_cbk(adc_callback_args_t * cb_data);
static ADC_Container adc(0,ADC_irq_cbk);
static ADC_Container adc1(1,ADC_irq_cbk);
static ADCIrqCbk_f scan_complete_cbk = nullptr;
static ADCIrqCbk_f scan_complete_b_cbk = nullptr;
static ADCIrqCbk_f window_compare_a_cbk = nullptr;
static ADCIrqCbk_f window_compare_b_cbk = nullptr;
static void readAllGroupA(ADC_Container *_adc) {
for(int i = 0; i < MAX_ADC_CHANNELS; i++) {
if(_adc->channel_cfg.scan_mask & (1 << i)) {
//is the channel active -> yes, read it
R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i);
}
}
}
static void readAllGroupB(ADC_Container *_adc) {
for(int i = 0; i < MAX_ADC_CHANNELS; i++) {
if(_adc->channel_cfg.scan_mask_group_b & (1 << i)) {
//is the channel active -> yes, read it
R_ADC_Read(&(_adc->ctrl), (adc_channel_t)i, analog_values_by_channels + i);
}
}
}
static void ADC_irq_cbk(adc_callback_args_t * cb_data) {
if(cb_data->event == ADC_EVENT_SCAN_COMPLETE) {
if(scan_complete_cbk != nullptr) {
if(cb_data->unit == 0) {
readAllGroupA(&adc);
}
else if(cb_data->unit == 1) {
readAllGroupA(&adc1);
}
scan_complete_cbk(cb_data->unit);
}
}
else if(cb_data->event == ADC_EVENT_SCAN_COMPLETE_GROUP_B) {
if(scan_complete_b_cbk != nullptr) {
if(cb_data->unit == 0) {
readAllGroupB(&adc);
}
else if(cb_data->unit == 1) {
readAllGroupB(&adc1);
}
scan_complete_b_cbk(cb_data->unit);
}
}
else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_A) {
if(window_compare_a_cbk != nullptr) {
window_compare_a_cbk(cb_data->unit);
}
}
else if(cb_data->event == ADC_EVENT_WINDOW_COMPARE_B) {
if(window_compare_b_cbk != nullptr) {
window_compare_b_cbk(cb_data->unit);
}
}
}
/* -------------------------------------------------------------------------- */
static ADC_Container *get_ADC_container_ptr(int32_t pin, uint16_t &cfg) {
/* -------------------------------------------------------------------------- */
ADC_Container *rv = nullptr;
auto cfg_adc = getPinCfgs(pin, PIN_CFG_REQ_ADC);
if(cfg_adc[0] > 0 ) {
if(IS_ADC1(cfg_adc[0])) {
rv = &adc1;
}
else {
rv = &adc;
}
}
cfg = cfg_adc[0];
return rv;
}
/* END of verbatim
*/
//////////////////// ADC //////////////
void startScan(int pin)
{
int32_t adc_idx = digitalPinToAnalogPin(pin);
ADC_Container *_adc = get_ADC_container_ptr(adc_idx, cfg_adc);
_adc->cfg.mode = ADC_MODE_SINGLE_SCAN;
pinPeripheral(digitalPinToBspPin(adc_idx), (uint32_t)IOPORT_CFG_ANALOG_ENABLE);
_adc->channel_cfg.scan_mask |= (1 << GET_CHANNEL(cfg_adc));
R_ADC_Open(&(_adc->ctrl), &(_adc->cfg));
R_ADC_CallbackSet(&(_adc->ctrl), adc_callback, p_context, p_callback_memory);
R_ADC_ScanCfg(&(_adc->ctrl), &(_adc->channel_cfg));
R_ADC_ScanStart(&(_adc->ctrl));
}
uint16_t readADC(int pin)
{
uint16_t result;
int32_t adc_idx = digitalPinToAnalogPin(pin);
ADC_Container *_adc = get_ADC_container_ptr(adc_idx, cfg_adc);
R_ADC_Read(&(_adc->ctrl), (adc_channel_t)GET_CHANNEL(cfg_adc), &result);
return result;
}