-
Notifications
You must be signed in to change notification settings - Fork 1
/
adc.c
152 lines (115 loc) · 3.3 KB
/
adc.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
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
/* ************************************************************************** */
/** ADC
@Company
ShimaneJohoshoriCenter.inc
@File Name
adc.c
@Summary
ADC processing
@Description
mruby/c function army
*/
/* ************************************************************************** */
#include "pic32mx.h"
#include "gpio.h"
#include "mrubyc.h"
/*! ADC handle
*/
typedef struct ADC_HANDLE {
PIN_HANDLE pin;
uint8_t channel;
} ADC_HANDLE;
#if defined(__32MX170F256B__) || defined(__PIC32MX170F256B__)
/*
Pin assign vs ADC channel table.
*/
static const ADC_HANDLE adc_handle_[] = {
{{1, 0}, 0}, // AN0=RA0
{{1, 1}, 1}, // AN1=RA1
{{2, 0}, 2}, // AN2=RB0
{{2, 1}, 3}, // AN3=RB1
{{2, 2}, 4}, // AN4=RB2
{{2, 3}, 5}, // AN5=RB3
{{2,15}, 9}, // AN9=RB15
{{2,14}, 10}, // AN10=RB14
{{2,13}, 11}, // AN11=RB13
{{2,12}, 12}, // AN12=RB12
};
#else
#include "adc_dependent.h"
#endif
/* ================================ C codes ================================ */
/* ============================= mruby/c codes ============================= */
/*! constructor
adc1 = ADC.new( num ) # num: pin number of Rboard
adc1 = ADC.new("A0") # PIC origined pin assingment.
# Rboard grove ADC terminal
adc1 = ADC.new("B14")
adc2 = ADC.new("B15")
*/
static void c_adc_new(mrbc_vm *vm, mrbc_value v[], int argc)
{
if( argc != 1 ) goto ERROR_RETURN;
PIN_HANDLE pin;
if( set_pin_handle( &pin, &v[1] ) != 0 ) goto ERROR_RETURN;
// find ADC channel from adc_handle_ table.
static const int NUM = sizeof(adc_handle_)/sizeof(ADC_HANDLE);
int i;
for( i = 0; i < NUM; i++ ) {
if( (adc_handle_[i].pin.port == pin.port) &&
(adc_handle_[i].pin.num == pin.num) ) break;
}
if( i == NUM ) goto ERROR_RETURN;
// allocate instance with ADC_HANDLE table pointer.
mrbc_value val = mrbc_instance_new(vm, v[0].cls, sizeof(ADC_HANDLE *));
*(const ADC_HANDLE **)(val.instance->data) = &adc_handle_[i];
// set pin to analog input
gpio_setmode( &pin, GPIO_ANALOG|GPIO_IN );
v[0] = val;
return;
ERROR_RETURN:
mrbc_raise(vm, MRBC_CLASS(ArgumentError), "ADC initialize.");
}
static uint32_t read_sub(mrbc_vm *vm, mrbc_value v[], int argc)
{
ADC_HANDLE *hndl = *(ADC_HANDLE **)v[0].instance->data;
AD1CHSbits.CH0SA = hndl->channel;
AD1CON1bits.SAMP = 1;
while( !AD1CON1bits.DONE )
;
AD1CON1bits.DONE = 0;
return ADC1BUF0;
}
/*! read_voltage
adc1.read_voltage() -> Float
*/
static void c_adc_read_voltage(mrbc_vm *vm, mrbc_value v[], int argc)
{
uint32_t raw_val = read_sub( vm, v, argc );
SET_FLOAT_RETURN( raw_val * 3.3 / 1023 );
}
/*! read_raw
adc1.read_raw() -> Integer
*/
static void c_adc_read_raw(mrbc_vm *vm, mrbc_value v[], int argc)
{
uint32_t raw_val = read_sub( vm, v, argc );
SET_INT_RETURN( raw_val );
}
/*! Initializer
*/
void mrbc_init_class_adc(void)
{
AD1CON1 = 0x00e0; // SSRC=111 CLRASAM=0 ASAM=0 SAMP=0
AD1CON2 = 0x0000;
AD1CON3 = 0x1e09; // SAMC=1e(60us) ADCS=09(TAD=2us)
AD1CHS = 0x0000;
AD1CSSL = 0x0000;
// Enable ADC
AD1CON1bits.ADON = 1;
mrbc_class *adc = mrbc_define_class(0, "ADC", 0);
mrbc_define_method(0, adc, "new", c_adc_new);
mrbc_define_method(0, adc, "read_voltage", c_adc_read_voltage);
mrbc_define_method(0, adc, "read", c_adc_read_voltage);
mrbc_define_method(0, adc, "read_raw", c_adc_read_raw);
}