Skip to content

Commit 8d09640

Browse files
committed
stmhal: Add documentation in comments, and script to generate HTML.
Decided to write own script to pull documentation from comments in C code. Style for writing auto generated documentation is: start line with /// and then use standard markdown to write the comment. Keywords recognised by the scraper begin with backslash. See code for examples. Running: python gendoc.py modpyb.c accel.c adc.c dac.c extint.c i2c.c led.c pin.c rng.c servo.c spi.c uart.c usrsw.c, will generate a HTML structure in gendoc-out/. gendoc.py is crude but functional. Needed something quick, and this was it.
1 parent 186e463 commit 8d09640

File tree

14 files changed

+935
-234
lines changed

14 files changed

+935
-234
lines changed

stmhal/accel.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414

1515
#if MICROPY_HW_HAS_MMA7660
1616

17+
/// \moduleref pyb
18+
/// \class Accel - accelerometer control
19+
///
20+
/// Accel is an object that controls the accelerometer.
21+
///
22+
/// Raw values are between -30 and 30.
23+
1724
#define MMA_ADDR (0x98)
1825
#define MMA_REG_X (0)
1926
#define MMA_REG_Y (1)
@@ -83,6 +90,8 @@ typedef struct _pyb_accel_obj_t {
8390

8491
STATIC pyb_accel_obj_t pyb_accel_obj;
8592

93+
/// \classmethod \constructor()
94+
/// Create and return an accelerometer object.
8695
STATIC mp_obj_t pyb_accel_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
8796
// check arguments
8897
mp_arg_check_num(n_args, n_kw, 0, 0, false);
@@ -100,32 +109,38 @@ STATIC mp_obj_t read_axis(int axis) {
100109
return mp_obj_new_int(MMA_AXIS_SIGNED_VALUE(data[0]));
101110
}
102111

112+
/// \method x()
113+
/// Get the x-axis value.
103114
STATIC mp_obj_t pyb_accel_x(mp_obj_t self_in) {
104115
return read_axis(MMA_REG_X);
105116
}
106-
107117
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_x_obj, pyb_accel_x);
108118

119+
/// \method y()
120+
/// Get the y-axis value.
109121
STATIC mp_obj_t pyb_accel_y(mp_obj_t self_in) {
110122
return read_axis(MMA_REG_Y);
111123
}
112-
113124
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_y_obj, pyb_accel_y);
114125

126+
/// \method z()
127+
/// Get the z-axis value.
115128
STATIC mp_obj_t pyb_accel_z(mp_obj_t self_in) {
116129
return read_axis(MMA_REG_Z);
117130
}
118-
119131
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_z_obj, pyb_accel_z);
120132

133+
/// \method tilt()
134+
/// Get the tilt register.
121135
STATIC mp_obj_t pyb_accel_tilt(mp_obj_t self_in) {
122136
uint8_t data[1];
123137
HAL_I2C_Mem_Read(&I2CHandle1, MMA_ADDR, MMA_REG_TILT, I2C_MEMADD_SIZE_8BIT, data, 1, 200);
124138
return mp_obj_new_int(data[0]);
125139
}
126-
127140
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_tilt_obj, pyb_accel_tilt);
128141

142+
/// \method filtered_xyz()
143+
/// Get a 3-tuple of filtered x, y and z values.
129144
STATIC mp_obj_t pyb_accel_filtered_xyz(mp_obj_t self_in) {
130145
pyb_accel_obj_t *self = self_in;
131146

@@ -146,15 +161,13 @@ STATIC mp_obj_t pyb_accel_filtered_xyz(mp_obj_t self_in) {
146161

147162
return mp_obj_new_tuple(3, tuple);
148163
}
149-
150164
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_accel_filtered_xyz_obj, pyb_accel_filtered_xyz);
151165

152166
STATIC mp_obj_t pyb_accel_read(mp_obj_t self_in, mp_obj_t reg) {
153167
uint8_t data[1];
154168
HAL_I2C_Mem_Read(&I2CHandle1, MMA_ADDR, mp_obj_get_int(reg), I2C_MEMADD_SIZE_8BIT, data, 1, 200);
155169
return mp_obj_new_int(data[0]);
156170
}
157-
158171
MP_DEFINE_CONST_FUN_OBJ_2(pyb_accel_read_obj, pyb_accel_read);
159172

160173
STATIC mp_obj_t pyb_accel_write(mp_obj_t self_in, mp_obj_t reg, mp_obj_t val) {
@@ -163,7 +176,6 @@ STATIC mp_obj_t pyb_accel_write(mp_obj_t self_in, mp_obj_t reg, mp_obj_t val) {
163176
HAL_I2C_Mem_Write(&I2CHandle1, MMA_ADDR, mp_obj_get_int(reg), I2C_MEMADD_SIZE_8BIT, data, 1, 200);
164177
return mp_const_none;
165178
}
166-
167179
MP_DEFINE_CONST_FUN_OBJ_3(pyb_accel_write_obj, pyb_accel_write);
168180

169181
STATIC const mp_map_elem_t pyb_accel_locals_dict_table[] = {

stmhal/adc.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@
1414
#include "genhdr/pins.h"
1515
#include "timer.h"
1616

17-
// Usage Model:
18-
//
19-
// adc = pyb.ADC(pin)
20-
// val = adc.read()
21-
//
22-
// adc = pyb.ADCAll(resolution)
23-
// val = adc.read_channel(channel)
24-
// val = adc.read_core_temp()
25-
// val = adc.read_core_vbat()
26-
// val = adc.read_core_vref()
17+
/// \moduleref pyb
18+
/// \class ADC - analog to digital conversion: read analog values on a pin
19+
///
20+
/// Usage:
21+
///
22+
/// adc = pyb.ADC(pin) # create an analog object from a pin
23+
/// val = adc.read() # read an analog value
24+
///
25+
/// adc = pyb.ADCAll(resolution) # creale an ADCAll object
26+
/// val = adc.read_channel(channel) # read the given channel
27+
/// val = adc.read_core_temp() # read MCU temperature
28+
/// val = adc.read_core_vbat() # read MCU VBAT
29+
/// val = adc.read_core_vref() # read MCU VREF
2730

2831
/* ADC defintions */
2932
#define ADCx (ADC1)
@@ -118,6 +121,9 @@ STATIC void adc_print(void (*print)(void *env, const char *fmt, ...), void *env,
118121
print(env, " channel=%lu>", self->channel);
119122
}
120123

124+
/// \classmethod \constructor(pin)
125+
/// Create an ADC object associated with the given pin.
126+
/// This allows you to then read analog values on that pin.
121127
STATIC mp_obj_t adc_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
122128
// check number of arguments
123129
mp_arg_check_num(n_args, n_kw, 1, 1, false);
@@ -155,15 +161,30 @@ STATIC mp_obj_t adc_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
155161
return o;
156162
}
157163

164+
/// \method read()
165+
/// Read the value on the analog pin and return it. The returned value
166+
/// will be between 0 and 4095.
158167
STATIC mp_obj_t adc_read(mp_obj_t self_in) {
159168
pyb_obj_adc_t *self = self_in;
160169

161170
uint32_t data = adc_read_channel(&self->handle);
162171
return mp_obj_new_int(data);
163172
}
164-
165173
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
166174

175+
/// \method read_timed(buf, freq)
176+
/// Read analog values into the given buffer at the given frequency.
177+
///
178+
/// Example:
179+
///
180+
/// adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
181+
/// buf = bytearray(100) # create a buffer of 100 bytes
182+
/// adc.read_timed(buf, 10) # read analog values into buf at 10Hz
183+
/// # this will take 10 seconds to finish
184+
/// for val in buf: # loop over all values
185+
/// print(val) # print the value out
186+
///
187+
/// This function does not allocate any memory.
167188
STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_in) {
168189
pyb_obj_adc_t *self = self_in;
169190

@@ -196,7 +217,6 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
196217

197218
return mp_obj_new_int(bufinfo.len);
198219
}
199-
200220
STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_obj, adc_read_timed);
201221

202222
STATIC const mp_map_elem_t adc_locals_dict_table[] = {

stmhal/dac.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
#include "timer.h"
1414
#include "dac.h"
1515

16+
/// \moduleref pyb
17+
/// \class DAC - digital to analog conversion
18+
///
19+
1620
STATIC DAC_HandleTypeDef DAC_Handle;
1721

1822
void dac_init(void) {

stmhal/extint.c

Lines changed: 84 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,58 +15,52 @@
1515
#include "pin.h"
1616
#include "extint.h"
1717

18-
// Usage Model:
19-
//
20-
// There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
21-
// and the remaining 6 are from internal sources.
22-
//
23-
// For lines 0 thru 15, a given line can map to the corresponding line from an
24-
// arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
25-
// line 1 can map to Px1 where x is A, B, C, ...
26-
//
27-
// def callback(line):
28-
// print("line =", line)
29-
//
30-
// # Note: ExtInt will automatically configure the gpio line as an input.
31-
// extint = pyb.ExtInt(pin, pyb.ExtInt.IRQ_FALLING, pyb.GPIO.PULL_UP, callback)
32-
//
33-
// Now every time a falling edge is seen on the X1 pin, the callback will be
34-
// called. Caution: mechanical pushbuttons have "bounce" and pushing or
35-
// releasing a switch will often generate multiple edges.
36-
// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
37-
// explanation, along with various techniques for debouncing.
38-
//
39-
// Trying to register 2 callbacks onto the same pin will throw an exception.
40-
//
41-
// If pin is passed as an integer, then it is assumed to map to one of the
42-
// internal interrupt sources, and must be in the range 16 thru 22.
43-
//
44-
// All other pin objects go through the pin mapper to come up with one of the
45-
// gpio pins.
46-
//
47-
// extint = pyb.ExtInt(pin, mode, pull, callback)
48-
//
49-
// Valid modes are pyb.ExtInt.IRQ_RISING, pyb.ExtInt.IRQ_FALLING,
50-
// pyb.ExtInt.IRQ_RISING_FALLING, pyb.ExtInt.EVT_RISING,
51-
// pyb.ExtInt.EVT_FALLING, and pyb.ExtInt.EVT_RISING_FALLING.
52-
//
53-
// Only the IRQ_xxx modes have been tested. The EVT_xxx modes have
54-
// something to do with sleep mode and the WFE instruction.
55-
//
56-
// Valid pull values are pyb.GPIO.PULL_UP, pyb.GPIO.PULL_DOWN, pyb.GPIO.PULL_NONE.
57-
//
58-
// extint.line() will return the line number that pin was mapped to.
59-
// extint.disable() can be use to disable the interrupt associated with a given
60-
// exti object. This could be useful for debouncing.
61-
// extint.enable() enables a disabled interrupt
62-
// extint.swint() will allow the callback to be triggered from software.
63-
//
64-
// pyb.ExtInt.regs() will dump the values of the EXTI registers.
65-
//
66-
// There is also a C API, so that drivers which require EXTI interrupt lines
67-
// can also use this code. See extint.h for the available functions and
68-
// usrsw.h for an example of using this.
69-
//
18+
/// \moduleref pyb
19+
/// \class ExtInt - configure I/O pins to interrupt on external events
20+
///
21+
/// There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
22+
/// and the remaining 6 are from internal sources.
23+
///
24+
/// For lines 0 thru 15, a given line can map to the corresponding line from an
25+
/// arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
26+
/// line 1 can map to Px1 where x is A, B, C, ...
27+
///
28+
/// def callback(line):
29+
/// print("line =", line)
30+
///
31+
/// Note: ExtInt will automatically configure the gpio line as an input.
32+
///
33+
/// extint = pyb.ExtInt(pin, pyb.ExtInt.IRQ_FALLING, pyb.GPIO.PULL_UP, callback)
34+
///
35+
/// Now every time a falling edge is seen on the X1 pin, the callback will be
36+
/// called. Caution: mechanical pushbuttons have "bounce" and pushing or
37+
/// releasing a switch will often generate multiple edges.
38+
/// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
39+
/// explanation, along with various techniques for debouncing.
40+
///
41+
/// Trying to register 2 callbacks onto the same pin will throw an exception.
42+
///
43+
/// If pin is passed as an integer, then it is assumed to map to one of the
44+
/// internal interrupt sources, and must be in the range 16 thru 22.
45+
///
46+
/// All other pin objects go through the pin mapper to come up with one of the
47+
/// gpio pins.
48+
///
49+
/// extint = pyb.ExtInt(pin, mode, pull, callback)
50+
///
51+
/// Valid modes are pyb.ExtInt.IRQ_RISING, pyb.ExtInt.IRQ_FALLING,
52+
/// pyb.ExtInt.IRQ_RISING_FALLING, pyb.ExtInt.EVT_RISING,
53+
/// pyb.ExtInt.EVT_FALLING, and pyb.ExtInt.EVT_RISING_FALLING.
54+
///
55+
/// Only the IRQ_xxx modes have been tested. The EVT_xxx modes have
56+
/// something to do with sleep mode and the WFE instruction.
57+
///
58+
/// Valid pull values are pyb.GPIO.PULL_UP, pyb.GPIO.PULL_DOWN, pyb.GPIO.PULL_NONE.
59+
///
60+
/// There is also a C API, so that drivers which require EXTI interrupt lines
61+
/// can also use this code. See extint.h for the available functions and
62+
/// usrsw.h for an example of using this.
63+
7064
// TODO Add python method to change callback object.
7165

7266
#define EXTI_OFFSET (EXTI_BASE - PERIPH_BASE)
@@ -204,29 +198,45 @@ void extint_swint(uint line) {
204198
EXTI->SWIER = (1 << line);
205199
}
206200

201+
/// \method line()
202+
/// Return the line number that the pin is mapped to.
207203
STATIC mp_obj_t extint_obj_line(mp_obj_t self_in) {
208204
extint_obj_t *self = self_in;
209205
return MP_OBJ_NEW_SMALL_INT(self->line);
210206
}
207+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_line_obj,i extint_obj_line);
211208

209+
/// \method enable()
210+
/// Enable a disabled interrupt.
212211
STATIC mp_obj_t extint_obj_enable(mp_obj_t self_in) {
213212
extint_obj_t *self = self_in;
214213
extint_enable(self->line);
215214
return mp_const_none;
216215
}
216+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_enable_obj, extint_obj_enable);
217217

218+
/// \method disable()
219+
/// Disable the interrupt associated with the ExtInt object.
220+
/// This could be useful for debouncing.
218221
STATIC mp_obj_t extint_obj_disable(mp_obj_t self_in) {
219222
extint_obj_t *self = self_in;
220223
extint_disable(self->line);
221224
return mp_const_none;
222225
}
226+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_disable_obj, extint_obj_disable);
223227

228+
/// \method swint()
229+
/// Trigger the callback from software.
224230
STATIC mp_obj_t extint_obj_swint(mp_obj_t self_in) {
225231
extint_obj_t *self = self_in;
226232
extint_swint(self->line);
227233
return mp_const_none;
228234
}
235+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_swint_obj, extint_obj_swint);
229236

237+
// TODO document as a staticmethod
238+
/// \classmethod regs()
239+
/// Dump the values of the EXTI registers.
230240
STATIC mp_obj_t extint_regs(void) {
231241
printf("EXTI_IMR %08lx\n", EXTI->IMR);
232242
printf("EXTI_EMR %08lx\n", EXTI->EMR);
@@ -236,9 +246,24 @@ STATIC mp_obj_t extint_regs(void) {
236246
printf("EXTI_PR %08lx\n", EXTI->PR);
237247
return mp_const_none;
238248
}
249+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(extint_regs_fun_obj, extint_regs);
250+
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(extint_regs_obj, (mp_obj_t)&extint_regs_fun_obj);
239251

240-
// line_obj = pyb.ExtInt(pin, mode, pull, callback)
241-
252+
/// \classmethod \constructor(pin, mode, pull, callback)
253+
/// Create an ExtInt object:
254+
///
255+
/// - `pin` is the pin on which to enable the interrupt (can be a pin object or any valid pin name).
256+
/// - `mode` can be one of:
257+
/// - `ExtInt.IRQ_RISING` - trigger on a rising edge;
258+
/// - `ExtInt.IRQ_FALLING` - trigger on a falling edge;
259+
/// - `ExtInt.IRQ_RISING_FALLING` - trigger on a rising or falling edge.
260+
/// - `pull` can be one of:
261+
/// - `pyb.Pin.PULL_NONE` - no pull up or down resistors;
262+
/// - `pyb.Pin.PULL_UP` - enable the pull-up resistor;
263+
/// - `pyb.Pin.PULL_DOWN` - enable the pull-down resistor.
264+
/// - `callback` is the function to call when the interrupt triggers. The
265+
/// callback function must accept exactly 1 argument, which is the line that
266+
/// triggered the interrupt.
242267
STATIC const mp_arg_t pyb_extint_make_new_args[] = {
243268
{ MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
244269
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
@@ -268,19 +293,17 @@ STATIC void extint_obj_print(void (*print)(void *env, const char *fmt, ...), voi
268293
print(env, "<ExtInt line=%u>", self->line);
269294
}
270295

271-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_line_obj, extint_obj_line);
272-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_enable_obj, extint_obj_enable);
273-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_disable_obj, extint_obj_disable);
274-
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_swint_obj, extint_obj_swint);
275-
STATIC MP_DEFINE_CONST_FUN_OBJ_0(extint_regs_fun_obj, extint_regs);
276-
STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(extint_regs_obj, (mp_obj_t)&extint_regs_fun_obj);
277-
278296
STATIC const mp_map_elem_t extint_locals_dict_table[] = {
279297
{ MP_OBJ_NEW_QSTR(MP_QSTR_line), (mp_obj_t)&extint_obj_line_obj },
280298
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&extint_obj_enable_obj },
281299
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&extint_obj_disable_obj },
282300
{ MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t)&extint_obj_swint_obj },
283301
{ MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&extint_regs_obj },
302+
303+
// class constants
304+
/// \constant IRQ_RISING - interrupt on a rising edge
305+
/// \constant IRQ_FALLING - interrupt on a falling edge
306+
/// \constant IRQ_RISING_FALLING - interrupt on a rising or falling edge
284307
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING) },
285308
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_FALLING) },
286309
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING_FALLING) },

0 commit comments

Comments
 (0)