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.
207203STATIC 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.
212211STATIC 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.
218221STATIC 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.
224230STATIC 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.
230240STATIC 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.
242267STATIC 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-
278296STATIC 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