Skip to content

Commit 22b4c28

Browse files
author
Daniel Campora
committed
cc3200: New ADC API.
1 parent 0e52d98 commit 22b4c28

7 files changed

Lines changed: 370 additions & 77 deletions

File tree

cc3200/boards/make-pins.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class AF:
3535
def __init__(self, name, idx, fn, unit, type):
3636
self.name = name
3737
self.idx = idx
38+
if self.idx > 15:
39+
self.idx = -1
3840
self.fn = fn
3941
self.unit = unit
4042
self.type = type
@@ -57,12 +59,16 @@ def add_af(self, af):
5759

5860
def print(self):
5961
print('// {}'.format(self.name))
60-
print('const pin_af_t pin_{}_af[] = {{'.format(self.name))
61-
for af in self.afs:
62-
af.print()
63-
print('};')
64-
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, pin_{}_af, {});\n'.format(
65-
self.name, self.name, self.port, self.gpio_bit, self.pin_num, self.name, len(self.afs)))
62+
if len(self.afs):
63+
print('const pin_af_t pin_{}_af[] = {{'.format(self.name))
64+
for af in self.afs:
65+
af.print()
66+
print('};')
67+
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, pin_{}_af, {});\n'.format(
68+
self.name, self.name, self.port, self.gpio_bit, self.pin_num, self.name, len(self.afs)))
69+
else:
70+
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, NULL, 0);\n'.format(
71+
self.name, self.name, self.port, self.gpio_bit, self.pin_num))
6672

6773
def print_header(self, hdr_file):
6874
hdr_file.write('extern pin_obj_t pin_{:s};\n'.format(self.name))

cc3200/mods/pybadc.c

Lines changed: 193 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,6 @@
5252
#include "mpexception.h"
5353

5454

55-
/// \moduleref pyb
56-
/// \class ADC - analog to digital conversion: read analog values on a pin
57-
///
58-
/// Usage:
59-
///
60-
/// adc = pyb.ADC('GP5') # create an adc object on the given pin (GP2, GP3, GP4 o GP5)
61-
/// adc.read() # read channel value
62-
///
63-
/// The sample rate is fixed to 62.5KHz and the resolution to 12 bits.
64-
65-
6655
/******************************************************************************
6756
DECLARE CONSTANTS
6857
******************************************************************************/
@@ -71,106 +60,179 @@
7160
/******************************************************************************
7261
DEFINE TYPES
7362
******************************************************************************/
63+
typedef struct {
64+
mp_obj_base_t base;
65+
bool enabled;
66+
} pyb_adc_obj_t;
67+
7468
typedef struct {
7569
mp_obj_base_t base;
7670
pin_obj_t *pin;
7771
byte channel;
7872
byte id;
79-
} pyb_adc_obj_t;
73+
bool enabled;
74+
} pyb_adc_channel_obj_t;
75+
8076

8177
/******************************************************************************
8278
DECLARE PRIVATE DATA
8379
******************************************************************************/
84-
STATIC pyb_adc_obj_t pyb_adc_obj[PYB_ADC_NUM_CHANNELS] = { {.pin = &pin_GP2, .channel = ADC_CH_0, .id = 1}, {.pin = &pin_GP3, .channel = ADC_CH_1, .id = 2},
85-
{.pin = &pin_GP4, .channel = ADC_CH_2, .id = 2}, {.pin = &pin_GP5, .channel = ADC_CH_3, .id = 4} };
80+
STATIC pyb_adc_channel_obj_t pyb_adc_channel_obj[PYB_ADC_NUM_CHANNELS] = { {.pin = &pin_GP2, .channel = ADC_CH_0, .id = 0, .enabled = false},
81+
{.pin = &pin_GP3, .channel = ADC_CH_1, .id = 1, .enabled = false},
82+
{.pin = &pin_GP4, .channel = ADC_CH_2, .id = 2, .enabled = false},
83+
{.pin = &pin_GP5, .channel = ADC_CH_3, .id = 3, .enabled = false} };
84+
STATIC pyb_adc_obj_t pyb_adc_obj = {.enabled = false};
85+
86+
STATIC const mp_obj_type_t pyb_adc_channel_type;
87+
88+
/******************************************************************************
89+
DECLARE PRIVATE FUNCTIONS
90+
******************************************************************************/
91+
STATIC mp_obj_t adc_channel_deinit(mp_obj_t self_in);
8692

8793
/******************************************************************************
8894
DEFINE PUBLIC FUNCTIONS
8995
******************************************************************************/
90-
STATIC void pybadc_init (pyb_adc_obj_t *self) {
91-
// configure the pin in analog mode
92-
pin_config (self->pin, -1, PIN_TYPE_ANALOG, PIN_TYPE_STD, -1, PIN_STRENGTH_2MA);
93-
// enable the ADC channel
94-
MAP_ADCChannelEnable(ADC_BASE, self->channel);
96+
STATIC void pyb_adc_init (pyb_adc_obj_t *self) {
9597
// enable and configure the timer
9698
MAP_ADCTimerConfig(ADC_BASE, (1 << 17) - 1);
9799
MAP_ADCTimerEnable(ADC_BASE);
98100
// enable the ADC peripheral
99101
MAP_ADCEnable(ADC_BASE);
102+
self->enabled = true;
103+
}
104+
105+
STATIC void pyb_adc_check_init(void) {
106+
// not initialized
107+
if (!pyb_adc_obj.enabled) {
108+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
109+
}
110+
}
111+
112+
STATIC void pyb_adc_channel_init (pyb_adc_channel_obj_t *self) {
113+
// the ADC block must be enabled first
114+
pyb_adc_check_init();
115+
// configure the pin in analog mode
116+
pin_config (self->pin, -1, PIN_TYPE_ANALOG, PIN_TYPE_STD, -1, PIN_STRENGTH_2MA);
117+
// enable the ADC channel
118+
MAP_ADCChannelEnable(ADC_BASE, self->channel);
119+
self->enabled = true;
120+
}
121+
122+
STATIC void pyb_adc_deinit_all_channels (void) {
123+
for (int i = 0; i < PYB_ADC_NUM_CHANNELS; i++) {
124+
adc_channel_deinit(&pyb_adc_channel_obj[i]);
125+
}
100126
}
101127

102128
/******************************************************************************/
103129
/* Micro Python bindings : adc object */
104130

105131
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
106132
pyb_adc_obj_t *self = self_in;
107-
mp_printf(print, "<ADC1 channel=%u on %q>", self->id, self->pin->name);
133+
if (self->enabled) {
134+
mp_printf(print, "ADC(0, bits=12)");
135+
} else {
136+
mp_printf(print, "ADC(0)");
137+
}
108138
}
109139

110-
/// \classmethod \constructor(pin)
111-
/// Create an ADC object associated with the given pin.
112-
/// This allows you to then read analog values on that pin.
113-
STATIC mp_obj_t adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
114-
// check number of arguments
115-
mp_arg_check_num(n_args, n_kw, 1, 1, false);
116-
117-
// the argument passed is the pin
118-
const pin_obj_t *pin = (pin_obj_t *)pin_find(args[0]);
119-
for (int32_t idx = 0; idx < PYB_ADC_NUM_CHANNELS; idx++) {
120-
if (pin == pyb_adc_obj[idx].pin) {
121-
pyb_adc_obj_t *self = &pyb_adc_obj[idx];
122-
self->base.type = &pyb_adc_type;
123-
pybadc_init (self);
124-
// register it with the sleep module
125-
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybadc_init);
126-
return self;
127-
}
140+
STATIC const mp_arg_t pyb_adc_init_args[] = {
141+
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
142+
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 12} },
143+
};
144+
STATIC mp_obj_t adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
145+
// parse args
146+
mp_map_t kw_args;
147+
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
148+
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_adc_init_args)];
149+
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_adc_init_args, args);
150+
151+
// check the peripheral id
152+
if (args[0].u_int != 0) {
153+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
128154
}
129-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
130-
}
131155

132-
/// \method read()
133-
/// Read the value on the analog pin and return it. The returned value
134-
/// will be between 0 and 4095.
135-
STATIC mp_obj_t adc_read(mp_obj_t self_in) {
136-
pyb_adc_obj_t *self = self_in;
137-
uint32_t sample;
156+
// check the number of bits
157+
if (args[1].u_int != 12) {
158+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
159+
}
138160

139-
// wait until a new value is available
140-
while (!MAP_ADCFIFOLvlGet(ADC_BASE, self->channel));
141-
// read the sample
142-
sample = MAP_ADCFIFORead(ADC_BASE, self->channel);
143-
// the 12 bit sampled value is stored in bits [13:2]
144-
return MP_OBJ_NEW_SMALL_INT((sample & 0x3FFF) >> 2);
145-
}
146-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
161+
// setup the object
162+
pyb_adc_obj_t *self = &pyb_adc_obj;
163+
self->base.type = &pyb_adc_type;
147164

148-
/// \method init()
149-
/// Enable the adc channel
150-
STATIC mp_obj_t adc_init(mp_obj_t self_in) {
151-
pyb_adc_obj_t *self = self_in;
165+
// initialize and register with the sleep module
166+
pyb_adc_init(self);
167+
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pyb_adc_init);
168+
return self;
169+
}
152170

153-
pybadc_init(self);
171+
STATIC mp_obj_t adc_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
172+
// parse args
173+
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_adc_init_args) - 1];
174+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_adc_init_args[1], args);
175+
// check the number of bits
176+
if (args[0].u_int != 12) {
177+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
178+
}
179+
pyb_adc_init(pos_args[0]);
154180
return mp_const_none;
155181
}
156-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_init_obj, adc_init);
182+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adc_init_obj, 1, adc_init);
157183

158-
/// \method deinit()
159-
/// Disable the adc channel
160184
STATIC mp_obj_t adc_deinit(mp_obj_t self_in) {
161185
pyb_adc_obj_t *self = self_in;
162-
163-
MAP_ADCChannelDisable(ADC_BASE, self->channel);
186+
// first deinit all channels
187+
pyb_adc_deinit_all_channels();
188+
MAP_ADCDisable(ADC_BASE);
189+
self->enabled = false;
164190
// unregister it with the sleep module
165191
pybsleep_remove ((const mp_obj_t)self);
166192
return mp_const_none;
167193
}
168194
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_deinit_obj, adc_deinit);
169195

196+
STATIC mp_obj_t adc_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
197+
STATIC const mp_arg_t pyb_adc_channel_args[] = {
198+
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} },
199+
{ MP_QSTR_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
200+
};
201+
202+
// parse args
203+
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_adc_channel_args)];
204+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_adc_channel_args, args);
205+
206+
uint ch_id;
207+
if (args[0].u_obj != mp_const_none) {
208+
ch_id = mp_obj_get_int(args[0].u_obj);
209+
if (ch_id >= PYB_ADC_NUM_CHANNELS) {
210+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_os_resource_not_avaliable));
211+
}
212+
else if (args[1].u_obj != mp_const_none) {
213+
uint pin_ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
214+
if (ch_id != pin_ch_id) {
215+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
216+
}
217+
}
218+
} else {
219+
ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
220+
}
221+
222+
// setup the object
223+
pyb_adc_channel_obj_t *self = &pyb_adc_channel_obj[ch_id];
224+
self->base.type = &pyb_adc_channel_type;
225+
pyb_adc_channel_init (self);
226+
// register it with the sleep module
227+
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pyb_adc_channel_init);
228+
return self;
229+
}
230+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adc_channel_obj, 1, adc_channel);
231+
170232
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
171-
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj },
172233
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&adc_init_obj },
173234
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&adc_deinit_obj },
235+
{ MP_OBJ_NEW_QSTR(MP_QSTR_channel), (mp_obj_t)&adc_channel_obj },
174236
};
175237

176238
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
@@ -183,3 +245,69 @@ const mp_obj_type_t pyb_adc_type = {
183245
.locals_dict = (mp_obj_t)&adc_locals_dict,
184246
};
185247

248+
STATIC void adc_channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
249+
pyb_adc_channel_obj_t *self = self_in;
250+
if (self->enabled) {
251+
mp_printf(print, "ADCChannel(%u, pin=%q)", self->id, self->pin->name);
252+
} else {
253+
mp_printf(print, "ADCChannel(%u)", self->id);
254+
}
255+
}
256+
257+
STATIC mp_obj_t adc_channel_init(mp_obj_t self_in) {
258+
pyb_adc_channel_obj_t *self = self_in;
259+
// re-enable it
260+
pyb_adc_channel_init(self);
261+
return mp_const_none;
262+
}
263+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_init_obj, adc_channel_init);
264+
265+
STATIC mp_obj_t adc_channel_deinit(mp_obj_t self_in) {
266+
pyb_adc_channel_obj_t *self = self_in;
267+
268+
MAP_ADCChannelDisable(ADC_BASE, self->channel);
269+
// unregister it with the sleep module
270+
pybsleep_remove ((const mp_obj_t)self);
271+
self->enabled = false;
272+
return mp_const_none;
273+
}
274+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_deinit_obj, adc_channel_deinit);
275+
276+
STATIC mp_obj_t adc_channel_value(mp_obj_t self_in) {
277+
pyb_adc_channel_obj_t *self = self_in;
278+
uint32_t value;
279+
280+
// the channel must be enabled
281+
if (!self->enabled) {
282+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
283+
}
284+
285+
// wait until a new value is available
286+
while (!MAP_ADCFIFOLvlGet(ADC_BASE, self->channel));
287+
// read the sample
288+
value = MAP_ADCFIFORead(ADC_BASE, self->channel);
289+
// the 12 bit sampled value is stored in bits [13:2]
290+
return MP_OBJ_NEW_SMALL_INT((value & 0x3FFF) >> 2);
291+
}
292+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_value_obj, adc_channel_value);
293+
294+
STATIC mp_obj_t adc_channel_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
295+
mp_arg_check_num(n_args, n_kw, 0, 0, false);
296+
return adc_channel_value (self_in);
297+
}
298+
299+
STATIC const mp_map_elem_t adc_channel_locals_dict_table[] = {
300+
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&adc_channel_init_obj },
301+
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&adc_channel_deinit_obj },
302+
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&adc_channel_value_obj },
303+
};
304+
305+
STATIC MP_DEFINE_CONST_DICT(adc_channel_locals_dict, adc_channel_locals_dict_table);
306+
307+
STATIC const mp_obj_type_t pyb_adc_channel_type = {
308+
{ &mp_type_type },
309+
.name = MP_QSTR_ADCChannel,
310+
.print = adc_channel_print,
311+
.call = adc_channel_call,
312+
.locals_dict = (mp_obj_t)&adc_channel_locals_dict,
313+
};

cc3200/mods/pybpin.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type)
184184
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
185185
}
186186

187+
uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit) {
188+
pin_obj_t *pin_o = pin_find(pin);
189+
for (int i = 0; i < pin_o->num_afs; i++) {
190+
if (pin_o->af_list[i].fn == fn && pin_o->af_list[i].unit == unit) {
191+
return pin_o->af_list[i].type;
192+
}
193+
}
194+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
195+
}
196+
187197
/******************************************************************************
188198
DEFINE PRIVATE FUNCTIONS
189199
******************************************************************************/

cc3200/mods/pybpin.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ enum {
8585
};
8686

8787
enum {
88-
PIN_TYPE_ADC_CH0 = -1,
89-
PIN_TYPE_ADC_CH1 = -1,
90-
PIN_TYPE_ADC_CH2 = -1,
91-
PIN_TYPE_ADC_CH3 = -1,
88+
PIN_TYPE_ADC_CH0 = 0,
89+
PIN_TYPE_ADC_CH1,
90+
PIN_TYPE_ADC_CH2,
91+
PIN_TYPE_ADC_CH3,
9292
};
9393

9494
typedef struct {
9595
qstr name;
96-
uint8_t idx;
96+
int8_t idx;
9797
uint8_t fn;
9898
uint8_t unit;
9999
uint8_t type;
@@ -136,5 +136,6 @@ void pin_config(pin_obj_t *self, int af, uint mode, uint type, int value, uint s
136136
pin_obj_t *pin_find(mp_obj_t user_obj);
137137
void pin_assign_pins_af (mp_obj_t *pins, uint32_t n_pins, uint32_t pull, uint32_t fn, uint32_t unit);
138138
uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type);
139+
uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit);
139140

140141
#endif // PYBPIN_H_

0 commit comments

Comments
 (0)