Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
73aee8da
Commit
73aee8da
authored
Mar 04, 2015
by
danicampora
Browse files
cc3200: Merge ExtInt class into Pin class.
Also add another method to change the pin's interrupt mode on the fly.
parent
26cbc913
Changes
12
Hide whitespace changes
Inline
Side-by-side
cc3200/application.mk
View file @
73aee8da
...
...
@@ -89,7 +89,6 @@ APP_MODS_SRC_C = $(addprefix mods/,\
modutime.c
\
modwlan.c
\
pybadc.c
\
pybextint.c
\
pybi2c.c
\
pybpin.c
\
pybrtc.c
\
...
...
cc3200/boards/cc3200_prefix.c
View file @
73aee8da
...
...
@@ -43,6 +43,7 @@
{ \
{ &pin_type }, \
.name = MP_QSTR_ ## p_pin_name, \
.callback = NULL, \
.port = PORT_A ## p_port, \
.type = PIN_TYPE_STD, \
.bit = (p_bit), \
...
...
cc3200/misc/pin_named_pins.c
View file @
73aee8da
...
...
@@ -67,3 +67,14 @@ const pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
}
return
NULL
;
}
const
pin_obj_t
*
pin_find_pin_by_port_bit
(
const
mp_obj_dict_t
*
named_pins
,
uint
port
,
uint
bit
)
{
mp_map_t
*
named_map
=
mp_obj_dict_get_map
((
mp_obj_t
)
named_pins
);
for
(
uint
i
=
0
;
i
<
named_map
->
used
;
i
++
)
{
if
((((
pin_obj_t
*
)
named_map
->
table
[
i
].
value
)
->
port
==
port
)
&&
(((
pin_obj_t
*
)
named_map
->
table
[
i
].
value
)
->
bit
==
bit
))
{
return
named_map
->
table
[
i
].
value
;
}
}
return
NULL
;
}
cc3200/mods/modpyb.c
View file @
73aee8da
...
...
@@ -54,7 +54,6 @@
#include
"task.h"
#include
"mpexception.h"
#include
"random.h"
#include
"pybextint.h"
#include
"pybadc.h"
#include
"pybi2c.h"
#include
"pybsd.h"
...
...
@@ -312,7 +311,6 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
#endif
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_Pin
),
(
mp_obj_t
)
&
pin_type
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_ExtInt
),
(
mp_obj_t
)
&
extint_type
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_ADC
),
(
mp_obj_t
)
&
pyb_adc_type
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_I2C
),
(
mp_obj_t
)
&
pyb_i2c_type
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_UART
),
(
mp_obj_t
)
&
pyb_uart_type
},
...
...
cc3200/mods/pybextint.c
deleted
100644 → 0
View file @
26cbc913
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2015 Daniel Campora
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include
<stdio.h>
#include
<stddef.h>
#include
<string.h>
#include
"py/mpstate.h"
#include MICROPY_HAL_H
#include
"py/runtime.h"
#include
"py/gc.h"
#include
"py/objlist.h"
#include
"inc/hw_types.h"
#include
"inc/hw_gpio.h"
#include
"inc/hw_ints.h"
#include
"inc/hw_memmap.h"
#include
"rom_map.h"
#include
"pin.h"
#include
"gpio.h"
#include
"pybpin.h"
#include
"pybextint.h"
#include
"mpexception.h"
#include
"interrupt.h"
#include
"cc3200_asm.h"
#include
"mperror.h"
/// \moduleref pyb
/// \class ExtInt - configure I/O pins to interrupt on external events
///
/// There are a maximum of 25 gpio interrupt lines.
///
/// Example callback:
///
/// def callback(line):
/// print(line.pin())
///
/// Note: ExtInt will automatically configure the gpio line as an input.
///
/// extint = pyb.ExtInt('GPIO10', pyb.ExtInt.IRQ_FALLING, pyb.GPIO.STD_PU, callback)
///
/// Now every time a falling edge is seen on the gpio pin, the callback will be
/// called. Caution: mechanical pushbuttons have "bounce" and pushing or
/// releasing a switch will often generate multiple edges.
/// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
/// explanation, along with various techniques for debouncing.
///
/// All pin objects go through the pin mapper to come up with one of the
/// gpio pins.
///
/// extint = pyb.ExtInt(pin, mode, pull, callback)
///
/// There is also a C API, so that drivers which require EXTI interrupt lines
/// can also use this code. See pybextint.h for the available functions.
STATIC
void
ExecuteIntCallback
(
extint_obj_t
*
self
);
STATIC
void
GPIOA0IntHandler
(
void
);
STATIC
void
GPIOA1IntHandler
(
void
);
STATIC
void
GPIOA2IntHandler
(
void
);
STATIC
void
GPIOA3IntHandler
(
void
);
STATIC
void
EXTI_Handler
(
uint
port
);
STATIC
extint_obj_t
*
extint_add
(
uint
pin_num
,
uint
port
,
uint
bit
)
{
extint_obj_t
*
self
=
m_new_obj
(
extint_obj_t
);
self
->
port
=
port
;
self
->
bit
=
bit
;
self
->
callback
=
NULL
;
self
->
pin_num
=
pin_num
;
// add it to the list
mp_obj_list_append
(
&
MP_STATE_PORT
(
pyb_extint_list
),
self
);
return
self
;
}
STATIC
extint_obj_t
*
extint_find
(
uint
port
,
uint8_t
bit
)
{
for
(
mp_uint_t
i
=
0
;
i
<
MP_STATE_PORT
(
pyb_extint_list
).
len
;
i
++
)
{
extint_obj_t
*
self
=
(
extint_obj_t
*
)
MP_STATE_PORT
(
pyb_extint_list
).
items
[
i
];
if
(
self
->
port
==
port
&&
self
->
bit
==
bit
)
{
return
self
;
}
}
return
NULL
;
}
/// \method line()
/// Return the pin number to which this external interrupt is mapped to.
STATIC
mp_obj_t
extint_obj_pin
(
mp_obj_t
self_in
)
{
extint_obj_t
*
self
=
self_in
;
return
MP_OBJ_NEW_SMALL_INT
(
self
->
pin_num
);
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
extint_obj_pin_obj
,
extint_obj_pin
);
/// \method enable()
/// Enable a disabled interrupt.
STATIC
mp_obj_t
extint_obj_enable
(
mp_obj_t
self_in
)
{
extint_obj_t
*
self
=
self_in
;
extint_enable
(
self
);
return
mp_const_none
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
extint_obj_enable_obj
,
extint_obj_enable
);
/// \method disable()
/// Disable the interrupt associated with the ExtInt object.
/// This could be useful for debouncing.
STATIC
mp_obj_t
extint_obj_disable
(
mp_obj_t
self_in
)
{
extint_obj_t
*
self
=
self_in
;
extint_disable
(
self
);
return
mp_const_none
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
extint_obj_disable_obj
,
extint_obj_disable
);
/// \method swint()
/// Trigger the callback from software.
STATIC
mp_obj_t
extint_obj_swint
(
mp_obj_t
self_in
)
{
extint_obj_t
*
self
=
self_in
;
extint_swint
(
self
);
return
mp_const_none
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
extint_obj_swint_obj
,
extint_obj_swint
);
/// \classmethod \constructor(pin, mode, pull, callback)
/// Create an ExtInt object:
///
/// - `pin` is the pin on which to enable the interrupt (can be a pin object or any valid pin name).
/// - `mode` can be one of:
/// - `ExtInt.IRQ_RISING` - trigger on a rising edge;
/// - `ExtInt.IRQ_FALLING` - trigger on a falling edge;
/// - `ExtInt.IRQ_RISING_FALLING` - trigger on a rising or falling edge.
/// - `pull` can be one of:
/// - `pyb.Pin.PULL_NONE` - no pull up or down resistors;
/// - `pyb.Pin.PULL_UP` - enable the pull-up resistor;
/// - `pyb.Pin.PULL_DOWN` - enable the pull-down resistor.
/// - `callback` is the function to call when the interrupt triggers. The
/// callback function must accept exactly 1 argument, which is the line that
/// triggered the interrupt.
STATIC
const
mp_arg_t
pyb_extint_make_new_args
[]
=
{
{
MP_QSTR_pin
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
{
MP_QSTR_mode
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_pull
,
MP_ARG_REQUIRED
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_callback
,
MP_ARG_REQUIRED
|
MP_ARG_OBJ
,
{.
u_obj
=
MP_OBJ_NULL
}
},
};
#define PYB_EXTINT_MAKE_NEW_NUM_ARGS MP_ARRAY_SIZE(pyb_extint_make_new_args)
STATIC
mp_obj_t
extint_make_new
(
mp_obj_t
type_in
,
mp_uint_t
n_args
,
mp_uint_t
n_kw
,
const
mp_obj_t
*
args
)
{
// parse args
mp_arg_val_t
vals
[
PYB_EXTINT_MAKE_NEW_NUM_ARGS
];
mp_arg_parse_all_kw_array
(
n_args
,
n_kw
,
args
,
PYB_EXTINT_MAKE_NEW_NUM_ARGS
,
pyb_extint_make_new_args
,
vals
);
extint_obj_t
*
self
=
extint_register
(
vals
[
0
].
u_obj
,
vals
[
1
].
u_int
,
vals
[
2
].
u_int
,
vals
[
3
].
u_obj
);
self
->
base
.
type
=
type_in
;
return
self
;
}
STATIC
void
extint_obj_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
self_in
,
mp_print_kind_t
kind
)
{
extint_obj_t
*
self
=
self_in
;
print
(
env
,
"<ExtInt pin=%u>"
,
self
->
pin_num
);
}
STATIC
const
mp_map_elem_t
extint_locals_dict_table
[]
=
{
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pin
),
(
mp_obj_t
)
&
extint_obj_pin_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_enable
),
(
mp_obj_t
)
&
extint_obj_enable_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_disable
),
(
mp_obj_t
)
&
extint_obj_disable_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_swint
),
(
mp_obj_t
)
&
extint_obj_swint_obj
},
// class constants
/// \constant IRQ_RISING - interrupt on a rising edge
/// \constant IRQ_FALLING - interrupt on a falling edge
/// \constant IRQ_RISING_FALLING - interrupt on a rising or falling edge
/// \constant IRQ_LOW_LEVEL - interrupt on a low level
/// \constant IRQ_HIGH_LEVEL - interrupt on a high level
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_IRQ_FALLING
),
MP_OBJ_NEW_SMALL_INT
(
GPIO_FALLING_EDGE
)
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_IRQ_RISING
),
MP_OBJ_NEW_SMALL_INT
(
GPIO_RISING_EDGE
)
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_IRQ_RISING_FALLING
),
MP_OBJ_NEW_SMALL_INT
(
GPIO_BOTH_EDGES
)
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_IRQ_LOW_LEVEL
),
MP_OBJ_NEW_SMALL_INT
(
GPIO_LOW_LEVEL
)
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_IRQ_HIGH_LEVEL
),
MP_OBJ_NEW_SMALL_INT
(
GPIO_HIGH_LEVEL
)
},
};
STATIC
MP_DEFINE_CONST_DICT
(
extint_locals_dict
,
extint_locals_dict_table
);
STATIC
void
ExecuteIntCallback
(
extint_obj_t
*
self
)
{
if
(
self
->
callback
!=
mp_const_none
)
{
// disable interrupts to avoid nesting
uint
primsk
=
disable_irq
();
// when executing code within a handler we must lock the GC to prevent
// any memory allocations. We must also catch any exceptions.
gc_lock
();
nlr_buf_t
nlr
;
if
(
nlr_push
(
&
nlr
)
==
0
)
{
mp_call_function_1
(
self
->
callback
,
self
);
nlr_pop
();
}
else
{
// uncaught exception; disable the callback so it doesn't run again
self
->
callback
=
mp_const_none
;
extint_disable
(
self
);
// printing an exception here will cause a stack overflow that ends up in a
// hard fault so, is better to signal the uncaught (probably non-recoverable)
// exception by blinkg the system led
mperror_signal_error
();
}
gc_unlock
();
enable_irq
(
primsk
);
}
}
STATIC
void
GPIOA0IntHandler
(
void
)
{
EXTI_Handler
(
GPIOA0_BASE
);
}
STATIC
void
GPIOA1IntHandler
(
void
)
{
EXTI_Handler
(
GPIOA1_BASE
);
}
STATIC
void
GPIOA2IntHandler
(
void
)
{
EXTI_Handler
(
GPIOA2_BASE
);
}
STATIC
void
GPIOA3IntHandler
(
void
)
{
EXTI_Handler
(
GPIOA3_BASE
);
}
// common interrupt handler
STATIC
void
EXTI_Handler
(
uint
port
)
{
extint_obj_t
*
self
;
uint32_t
bit
=
MAP_GPIOIntStatus
(
port
,
true
);
MAP_GPIOIntClear
(
port
,
bit
);
if
(
NULL
!=
(
self
=
extint_find
(
port
,
bit
)))
{
ExecuteIntCallback
(
self
);
}
}
const
mp_obj_type_t
extint_type
=
{
{
&
mp_type_type
},
.
name
=
MP_QSTR_ExtInt
,
.
print
=
extint_obj_print
,
.
make_new
=
extint_make_new
,
.
locals_dict
=
(
mp_obj_t
)
&
extint_locals_dict
,
};
void
extint_init0
(
void
)
{
mp_obj_list_init
(
&
MP_STATE_PORT
(
pyb_extint_list
),
0
);
}
extint_obj_t
*
extint_register
(
mp_obj_t
pin_obj
,
uint32_t
intmode
,
uint32_t
pull
,
mp_obj_t
callback
)
{
const
pin_obj_t
*
pin
;
extint_obj_t
*
self
;
void
*
handler
;
uint32_t
intnum
;
pin
=
pin_find
(
pin_obj
);
if
(
intmode
!=
GPIO_FALLING_EDGE
&&
intmode
!=
GPIO_RISING_EDGE
&&
intmode
!=
GPIO_BOTH_EDGES
&&
intmode
!=
GPIO_LOW_LEVEL
&&
intmode
!=
GPIO_HIGH_LEVEL
)
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_ValueError
,
mpexception_value_invalid_arguments
));
}
if
(
pull
!=
PIN_TYPE_STD
&&
pull
!=
PIN_TYPE_STD_PU
&&
pull
!=
PIN_TYPE_STD_PD
&&
pull
!=
PIN_TYPE_OD
&&
pull
!=
PIN_TYPE_OD_PU
&&
pull
!=
PIN_TYPE_OD_PD
)
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_ValueError
,
mpexception_value_invalid_arguments
));
}
if
(
NULL
==
(
self
=
extint_find
(
pin
->
port
,
pin
->
bit
)))
{
self
=
extint_add
(
pin
->
pin_num
,
pin
->
port
,
pin
->
bit
);
}
else
{
// we need to update the callback atomically, so we disable the line
// before we update anything.
extint_disable
(
self
);
}
// invalidate the callback
self
->
callback
=
NULL
;
// before enabling the interrupt, configure the gpio pin
pin_config
((
pin_obj_t
*
)
pin
,
PIN_MODE_0
,
GPIO_DIR_MODE_IN
,
pull
,
PIN_STRENGTH_4MA
);
MAP_GPIOIntTypeSet
(
pin
->
port
,
pin
->
bit
,
intmode
);
switch
(
pin
->
port
)
{
case
GPIOA0_BASE
:
handler
=
GPIOA0IntHandler
;
intnum
=
INT_GPIOA0
;
break
;
case
GPIOA1_BASE
:
handler
=
GPIOA1IntHandler
;
intnum
=
INT_GPIOA1
;
break
;
case
GPIOA2_BASE
:
handler
=
GPIOA2IntHandler
;
intnum
=
INT_GPIOA2
;
break
;
case
GPIOA3_BASE
:
default:
handler
=
GPIOA3IntHandler
;
intnum
=
INT_GPIOA3
;
break
;
}
MAP_GPIOIntRegister
(
pin
->
port
,
handler
);
// set the interrupt to the lowest priority, to make sure that no ther
// isr will be preemted by this one
MAP_IntPrioritySet
(
intnum
,
INT_PRIORITY_LVL_7
);
// set the new callback
self
->
callback
=
callback
;
// enable the interrupt just before leaving
extint_enable
(
self
);
return
self
;
}
void
extint_enable
(
extint_obj_t
*
self
)
{
MAP_GPIOIntClear
(
self
->
port
,
self
->
bit
);
MAP_GPIOIntEnable
(
self
->
port
,
self
->
bit
);
}
void
extint_disable
(
extint_obj_t
*
self
)
{
MAP_GPIOIntDisable
(
self
->
port
,
self
->
bit
);
}
void
extint_swint
(
extint_obj_t
*
self
)
{
ExecuteIntCallback
(
self
);
}
cc3200/mods/pybextint.h
deleted
100644 → 0
View file @
26cbc913
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
* Copyright (c) 2015 Daniel Campora
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef PYBEXTINT_H_
#define PYBEXTINT_H_
typedef
struct
{
mp_obj_base_t
base
;
mp_obj_t
callback
;
uint32_t
port
;
uint8_t
pin_num
;
uint8_t
bit
;
}
extint_obj_t
;
extern
const
mp_obj_type_t
extint_type
;
void
extint_init0
(
void
);
extint_obj_t
*
extint_register
(
mp_obj_t
pin_obj
,
uint32_t
intmode
,
uint32_t
pull
,
mp_obj_t
callback
);
void
extint_enable
(
extint_obj_t
*
self
);
void
extint_disable
(
extint_obj_t
*
self
);
void
extint_swint
(
extint_obj_t
*
self
);
#endif
/* PYBEXTINT_H_ */
cc3200/mods/pybpin.c
View file @
73aee8da
...
...
@@ -33,6 +33,7 @@
#include MICROPY_HAL_H
#include
"py/obj.h"
#include
"py/runtime.h"
#include
"py/gc.h"
#include
"inc/hw_types.h"
#include
"inc/hw_gpio.h"
#include
"inc/hw_ints.h"
...
...
@@ -41,9 +42,11 @@
#include
"pin.h"
#include
"prcm.h"
#include
"gpio.h"
#include
"interrupt.h"
#include
"pybpin.h"
#include
"pybsleep.h"
#include
"mpexception.h"
#include
"mperror.h"
/// \moduleref pyb
...
...
@@ -78,12 +81,46 @@
/// 1. Directly specify a Pin object
/// 2. Supply a string which matches a CPU pin name
/// 3. Provide a pin number
STATIC
mp_obj_t
pin_obj_init_helper
(
const
pin_obj_t
*
pin
,
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
);
///
/// \Interrupts:
//// You can also configure the Pin to generate interrupts
///
/// Example callback:
///
/// def pincb(pin):
/// print(pin.pin())
///
/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_FALLING, pyb.GPIO.STD_PU, pyb.S2MA, callback=pincb)
///
/// Now every time a falling edge is seen on the gpio pin, the callback will be
/// called. Caution: mechanical pushbuttons have "bounce" and pushing or
/// releasing a switch will often generate multiple edges.
/// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
/// explanation, along with various techniques for debouncing.
///
/// All pin objects go through the pin mapper to come up with one of the
/// gpio pins.
///
/// extint = pyb.Pin(pin, af, mode, pull, strength, callback)
///
/// There is also a C API, so that drivers which require Pin interrupts
/// can also use this code. See pybextint.h for the available functions.
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
******************************************************************************/
STATIC
void
ExecuteIntCallback
(
pin_obj_t
*
self
);
STATIC
void
GPIOA0IntHandler
(
void
);
STATIC
void
GPIOA1IntHandler
(
void
);
STATIC
void
GPIOA2IntHandler
(
void
);
STATIC
void
GPIOA3IntHandler
(
void
);
STATIC
void
EXTI_Handler
(
uint
port
);
STATIC
mp_obj_t
pin_obj_init_helper
(
pin_obj_t
*
pin
,
mp_uint_t
n_args
,
const
mp_obj_t
*
pos_args
,
mp_map_t
*
kw_args
);
STATIC
void
pin_obj_configure
(
const
pin_obj_t
*
self
);
/******************************************************************************
DEFINE PUBLIC FUNCTIONS
******************************************************************************/
void
pin_init0
(
void
)
{
}
...
...
@@ -136,6 +173,61 @@ void pin_config (pin_obj_t *self, uint af, uint mode, uint type, uint strength)
pybsleep_add
(
self
,
(
WakeUpCB_t
)
pin_obj_configure
);
}
void
pin_extint_register
(
pin_obj_t
*
self
,
uint32_t
intmode
,
mp_obj_t
callback
)
{
void
*
handler
;
uint32_t
intnum
;
// we need to update the callback atomically, so we disable the line
// before we update anything.
pin_extint_disable
(
self
);
// configure the interrupt type
MAP_GPIOIntTypeSet
(
self
->
port
,
self
->
bit
,
intmode
);
switch
(
self
->
port
)
{
case
GPIOA0_BASE
:
handler
=
GPIOA0IntHandler
;
intnum
=
INT_GPIOA0
;
break
;
case
GPIOA1_BASE
:
handler
=
GPIOA1IntHandler
;
intnum
=
INT_GPIOA1
;
break
;
case
GPIOA2_BASE
:
handler
=
GPIOA2IntHandler
;
intnum
=
INT_GPIOA2
;
break
;
case
GPIOA3_BASE
:
default:
handler
=
GPIOA3IntHandler
;
intnum
=
INT_GPIOA3
;
break
;
}
MAP_GPIOIntRegister
(
self
->
port
,
handler
);
// set the interrupt to the lowest priority, to make sure that
// no other ISRs will be preemted by this one
MAP_IntPrioritySet
(
intnum
,
INT_PRIORITY_LVL_7
);
// set the callback
self
->
callback
=
callback
;
// enable the interrupt just before leaving
pin_extint_enable
(
self
);
}
void
pin_extint_enable
(
pin_obj_t
*
self
)
{
MAP_GPIOIntClear
(
self
->
port
,
self
->
bit
);
MAP_GPIOIntEnable
(
self
->
port
,
self
->
bit
);
}
void
pin_extint_disable
(
pin_obj_t
*
self
)
{
MAP_GPIOIntDisable
(
self
->
port
,
self
->
bit
);
}
void
pin_extint_swint
(
pin_obj_t
*
self
)
{
ExecuteIntCallback
(
self
);
}
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
******************************************************************************/
STATIC
void
pin_obj_configure
(
const
pin_obj_t
*
self
)
{
// Skip all this if the pin is to be used in analog mode
if
(
self
->
type
!=
PYBPIN_ANALOG_TYPE
)
{
...
...
@@ -228,7 +320,7 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
mp_arg_check_num
(
n_args
,
n_kw
,
1
,
MP_OBJ_FUN_ARGS_MAX
,
true
);
// Run an argument through the mapper and return the result.
const
pin_obj_t
*
pin
=
pin_find
(
args
[
0
]);
pin_obj_t
*
pin
=
(
pin_obj_t
*
)
pin_find
(
args
[
0
]);
if
(
n_args
>
1
)
{
// pin af given, so configure it
...
...
@@ -263,42 +355,58 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
///
/// Returns: `None`.
STATIC
const
mp_arg_t
pin_init_args
[]
=
{
{
MP_QSTR_af
,
MP_ARG_REQUIRED
|
MP_ARG_INT
},
{
MP_QSTR_mode
,
MP_ARG_INT
,
{.
u_int
=
GPIO_DIR_MODE_OUT
}
},
{
MP_QSTR_type
,
MP_ARG_INT
,
{.
u_int
=
PIN_TYPE_STD
}
},
{
MP_QSTR_str
,
MP_ARG_INT
,
{.
u_int
=
PIN_STRENGTH_4MA
}
},
{
MP_QSTR_af
,
MP_ARG_REQUIRED
|
MP_ARG_INT
},
{
MP_QSTR_mode
,
MP_ARG_INT
,
{.
u_int
=
GPIO_DIR_MODE_OUT
}
},
{
MP_QSTR_type
,
MP_ARG_INT
,
{.
u_int
=
PIN_TYPE_STD
}
},
{
MP_QSTR_str
,
MP_ARG_INT
,
{.
u_int
=
PIN_STRENGTH_4MA
}
},
{
MP_QSTR_callback
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
};
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
STATIC
mp_obj_t
pin_obj_init_helper
(
const
pin_obj_t
*
self
,
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
STATIC
mp_obj_t
pin_obj_init_helper
(
pin_obj_t
*
self
,
mp_uint_t
n_args
,
const
mp_obj_t
*
pos_
args
,
mp_map_t
*
kw_args
)
{
// parse args
mp_arg_val_t
val
s
[
pin_INIT_NUM_ARGS
];
mp_arg_parse_all
(
n_args
,
args
,
kw_args
,
pin_INIT_NUM_ARGS
,
pin_init_args
,
val
s
);
mp_arg_val_t
arg
s
[
pin_INIT_NUM_ARGS
];
mp_arg_parse_all
(
n_args
,
pos_
args
,
kw_args
,
pin_INIT_NUM_ARGS
,
pin_init_args
,
arg
s
);
// get the af
uint
af
=
val
s
[
0
].
u_int
;
uint
af
=
arg
s
[
0
].
u_int
;
if
(
af
<
PIN_MODE_0
||
af
>
PIN_MODE_15
)
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_ValueError
,
mpexception_value_invalid_arguments
));
}
// get the io mode
uint
mode
=
vals
[
1
].
u_int
;