Skip to content

Commit 868fa82

Browse files
committed
cc3200: Add ADC module.
1 parent 5d2344d commit 868fa82

File tree

6 files changed

+251
-25
lines changed

6 files changed

+251
-25
lines changed

cc3200/application.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\
8989
modusocket.c \
9090
modutime.c \
9191
modwlan.c \
92+
pybadc.c \
9293
pybextint.c \
9394
pybi2c.c \
9495
pybpin.c \

cc3200/mods/modpyb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include "mpexception.h"
6363
#include "random.h"
6464
#include "pybextint.h"
65+
#include "pybadc.h"
6566
#include "pybi2c.h"
6667
#include "utils.h"
6768

@@ -313,6 +314,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
313314

314315
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
315316
{ MP_OBJ_NEW_QSTR(MP_QSTR_ExtInt), (mp_obj_t)&extint_type },
317+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
316318
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
317319
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
318320
};

cc3200/mods/pybadc.c

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013, 2014 Damien P. George
7+
* Copyright (c) 2015 Daniel Campora
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include <stdio.h>
29+
#include <string.h>
30+
31+
#include "mpconfig.h"
32+
#include MICROPY_HAL_H
33+
#include "py/nlr.h"
34+
#include "py/runtime.h"
35+
#include "py/binary.h"
36+
#include "py/gc.h"
37+
#include "bufhelper.h"
38+
#include "inc/hw_types.h"
39+
#include "inc/hw_adc.h"
40+
#include "inc/hw_ints.h"
41+
#include "inc/hw_memmap.h"
42+
#include "rom_map.h"
43+
#include "interrupt.h"
44+
#include "pin.h"
45+
#include "prcm.h"
46+
#include "adc.h"
47+
#include "pybadc.h"
48+
#include "pybpin.h"
49+
#include "pins.h"
50+
#include "mpexception.h"
51+
52+
53+
/// \moduleref pyb
54+
/// \class ADC - analog to digital conversion: read analog values on a pin
55+
///
56+
/// Usage:
57+
///
58+
/// adc = pyb.ADC(channel) # create an adc object on the given channel (0 to 3)
59+
/// adc.read() # read channel value
60+
///
61+
/// The sample rate is fixed to 62.5KHz and the resolution to 12 bits.
62+
63+
typedef struct _pyb_obj_adc_t {
64+
mp_obj_base_t base;
65+
byte channel;
66+
byte num;
67+
} pyb_obj_adc_t;
68+
69+
70+
/******************************************************************************/
71+
/* Micro Python bindings : adc object */
72+
73+
STATIC void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
74+
pyb_obj_adc_t *self = self_in;
75+
print(env, "<ADC, channel=%u>", self->num);
76+
}
77+
78+
/// \classmethod \constructor(channel)
79+
/// Create an ADC object associated with the given channel.
80+
/// This allows you to then read analog values on that pin.
81+
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) {
82+
// check number of arguments
83+
mp_arg_check_num(n_args, n_kw, 1, 1, false);
84+
85+
// the first argument is the channel number
86+
uint num = mp_obj_get_int(args[0]);
87+
const pin_obj_t *pin;
88+
uint channel;
89+
switch (num) {
90+
case 0:
91+
channel = ADC_CH_0;
92+
pin = &pin_GPIO2;
93+
break;
94+
case 1:
95+
channel = ADC_CH_1;
96+
pin = &pin_GPIO3;
97+
break;
98+
case 2:
99+
channel = ADC_CH_2;
100+
pin = &pin_GPIO4;
101+
break;
102+
case 3:
103+
channel = ADC_CH_3;
104+
pin = &pin_GPIO5;
105+
break;
106+
default:
107+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
108+
break;
109+
}
110+
111+
// disable the callback before re-configuring
112+
pyb_obj_adc_t *self = m_new_obj(pyb_obj_adc_t);
113+
self->base.type = &pyb_adc_type;
114+
self->channel = channel;
115+
self->num = num;
116+
117+
// configure the pin in analog mode
118+
pin_config (pin, 0, 0, PIN_TYPE_ANALOG, PIN_STRENGTH_2MA);
119+
120+
// enable the ADC channel
121+
MAP_ADCChannelEnable(ADC_BASE, channel);
122+
// enable and configure the timer
123+
MAP_ADCTimerConfig(ADC_BASE, (1 << 17) - 1);
124+
MAP_ADCTimerEnable(ADC_BASE);
125+
// enable the ADC peripheral
126+
MAP_ADCEnable(ADC_BASE);
127+
128+
return self;
129+
}
130+
131+
/// \method read()
132+
/// Read the value on the analog pin and return it. The returned value
133+
/// will be between 0 and 4095.
134+
STATIC mp_obj_t adc_read(mp_obj_t self_in) {
135+
pyb_obj_adc_t *self = self_in;
136+
uint32_t sample;
137+
138+
// wait until a new value is available
139+
while (!MAP_ADCFIFOLvlGet(ADC_BASE, self->channel));
140+
// read the sample
141+
sample = MAP_ADCFIFORead(ADC_BASE, self->channel);
142+
// the 12 bit sampled value is stored in bits [13:2]
143+
return MP_OBJ_NEW_SMALL_INT((sample & 0x3FFF) >> 2);
144+
}
145+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
146+
147+
/// \method enable()
148+
/// Enable the adc channel
149+
STATIC mp_obj_t adc_enable(mp_obj_t self_in) {
150+
pyb_obj_adc_t *self = self_in;
151+
152+
MAP_ADCChannelEnable(ADC_BASE, self->channel);
153+
return mp_const_none;
154+
}
155+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_enable_obj, adc_enable);
156+
157+
/// \method disable()
158+
/// Disable the adc channel
159+
STATIC mp_obj_t adc_disable(mp_obj_t self_in) {
160+
pyb_obj_adc_t *self = self_in;
161+
162+
MAP_ADCChannelDisable(ADC_BASE, self->channel);
163+
return mp_const_none;
164+
}
165+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_disable_obj, adc_disable);
166+
167+
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
168+
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&adc_disable_obj },
169+
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj },
170+
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&adc_enable_obj },
171+
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&adc_disable_obj },
172+
};
173+
174+
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
175+
176+
const mp_obj_type_t pyb_adc_type = {
177+
{ &mp_type_type },
178+
.name = MP_QSTR_ADC,
179+
.print = adc_print,
180+
.make_new = adc_make_new,
181+
.locals_dict = (mp_obj_t)&adc_locals_dict,
182+
};
183+

cc3200/mods/pybadc.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013, 2014 Damien P. George
7+
* Copyright (c) 2015 Daniel Campora
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#ifndef PYBADC_H_
29+
#define PYBADC_H_
30+
31+
extern const mp_obj_type_t pyb_adc_type;
32+
33+
#endif /* PYBADC_H_ */

cc3200/mods/pybpin.c

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include <stdint.h>
3030
#include <string.h>
3131

32-
#include "py/mpstate.h"
3332
#include "mpconfig.h"
3433
#include MICROPY_HAL_H
3534
#include "nlr.h"
@@ -115,31 +114,33 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
115114
}
116115

117116
void pin_config(const pin_obj_t *self, uint af, uint mode, uint type, uint strength) {
118-
// PIN_MODE_0 means it stays as a Pin, else, another peripheral will take control of it
119-
if (af == PIN_MODE_0) {
120-
// enable the peripheral clock for the GPIO port of this pin
121-
switch (self->port) {
122-
case PORT_A0:
123-
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
124-
break;
125-
case PORT_A1:
126-
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
127-
break;
128-
case PORT_A2:
129-
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA2, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
130-
break;
131-
case PORT_A3:
132-
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
133-
break;
134-
default:
135-
break;
117+
// Skip all this if the pin is to be used in analog mode
118+
if (type != PIN_TYPE_ANALOG) {
119+
// PIN_MODE_0 means it stays as a Pin, else, another peripheral will take control of it
120+
if (af == PIN_MODE_0) {
121+
// enable the peripheral clock for the GPIO port of this pin
122+
switch (self->port) {
123+
case PORT_A0:
124+
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
125+
break;
126+
case PORT_A1:
127+
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
128+
break;
129+
case PORT_A2:
130+
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA2, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
131+
break;
132+
case PORT_A3:
133+
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
134+
break;
135+
default:
136+
break;
137+
}
138+
// configure the direction
139+
MAP_GPIODirModeSet(self->port, self->bit, mode);
136140
}
137-
// configure the direction
138-
MAP_GPIODirModeSet(self->port, self->bit, mode);
141+
// now set the alternate function, strenght and type
142+
MAP_PinModeSet (self->pin_num, af);
139143
}
140-
141-
// now set the alternate function, strenght and type
142-
MAP_PinModeSet (self->pin_num, af);
143144
MAP_PinConfigSet(self->pin_num, strength, type);
144145
}
145146

@@ -433,7 +434,7 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
433434
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD) },
434435
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD_PU), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD_PU) },
435436
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD_PD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD_PD) },
436-
437+
437438
{ MP_OBJ_NEW_QSTR(MP_QSTR_S2MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_2MA) },
438439
{ MP_OBJ_NEW_QSTR(MP_QSTR_S4MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_4MA) },
439440
{ MP_OBJ_NEW_QSTR(MP_QSTR_S6MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_6MA) },

cc3200/qstrdefsport.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ Q(mem_write)
156156
Q(MASTER)
157157
Q(SLAVE)
158158

159+
// for ADC class
160+
Q(ADC)
161+
Q(read)
162+
Q(enable)
163+
Q(disable)
164+
159165
// for RTC class
160166
Q(RTC)
161167
Q(datetime)

0 commit comments

Comments
 (0)