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
ee31f71d
Commit
ee31f71d
authored
Feb 19, 2014
by
Dave Hylands
Browse files
Add EXTI support
Revamp usrsw to use new exti code. Add user switch callback function.
parent
790eed6f
Changes
13
Hide whitespace changes
Inline
Side-by-side
stm/Makefile
View file @
ee31f71d
...
...
@@ -67,13 +67,14 @@ SRC_C = \
audio.c
\
sdcard.c
\
i2c.c
\
usrsw.c
\
adc.c
\
rtc.c
\
file.c
\
pin.c
\
pin_named_pins.c
\
pin_map.c
\
exti.c
\
usrsw.c
\
# pybwlan.c
\
SRC_S
=
\
...
...
@@ -185,10 +186,21 @@ MAKE_PINS = boards/make-pins.py
BOARD_PINS
=
boards/
$(BOARD)
/pins.csv
AF_FILE
=
boards/stm32f4xx-af.csv
PREFIX_FILE
=
boards/stm32f4xx-prefix.c
$(BUILD)/pins_$(BOARD).c
:
$(MAKE_PINS) $(BOARD_PINS) $(AF_FILE) $(PREFIX_FILE)
GEN_PINS_SRC
=
$(BUILD)
/pins_
$(BOARD)
.c
GEN_PINS_HDR
=
$(BUILD)
/pins.h
# Making OBJ use an order-only depenedency on the generated pins.h file
# has the side effect of making the pins.h file before we actually compile
# any of the objects. The normal dependency generation will deal with the
# case when pins.h is modified. But when it doesn't exist, we don't know
# which source files might need it.
$(OBJ)
:
| $(BUILD)/pins.h
# Use a pattern rule here so that make will only call make-pins.py once to make
# both pins_$(BOARD).c and pins.h
$(BUILD)/%_$(BOARD).c $(BUILD)/%.h
:
boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE)
$(ECHO)
"Create
$@
"
$(Q)
python
$(MAKE_PINS)
--board
$(BOARD_PINS)
--af
$(AF_FILE)
--prefix
$(PREFIX_FILE)
>
$@
$(Q)
python
$(MAKE_PINS)
--board
$(BOARD_PINS)
--af
$(AF_FILE)
--prefix
$(PREFIX_FILE)
--hdr
$(GEN_PINS_HDR)
>
$(GEN_PINS_SRC)
$(BUILD)/pins_$(BOARD).o
:
$(BUILD)/pins_$(BOARD).c
$(
call
compile_c
)
...
...
stm/boards/NETDUINO_PLUS_2/mpconfigboard.h
View file @
ee31f71d
...
...
@@ -18,14 +18,11 @@
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_AUDIO (0)
#define USRSW_PORT (GPIOB)
#define USRSW_PIN (
GPIO_P
in_11)
// USRSW is pulled low. Pressing the button makes the input go high.
#define USRSW_PIN (
p
in_
B
11)
#define USRSW_PUPD (GPIO_PuPd_NOPULL)
#define USRSW_EXTI_PIN (EXTI_PinSource11)
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOB)
#define USRSW_EXTI_LINE (EXTI_Line11)
#define USRSW_EXTI_IRQN (EXTI15_10_IRQn)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
#define USRSW_PRESSED (1)
/* LED */
#define PYB_LED1_PORT (GPIOA) // Blue LED
...
...
stm/boards/PYBOARD3/mpconfigboard.h
View file @
ee31f71d
...
...
@@ -14,14 +14,11 @@
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_AUDIO (0)
#define USRSW_PORT (GPIOA)
#define USRSW_PIN (
GPIO_P
in_13)
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
#define USRSW_PIN (
p
in_
A
13)
#define USRSW_PUPD (GPIO_PuPd_UP)
#define USRSW_EXTI_PIN (EXTI_PinSource13)
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOA)
#define USRSW_EXTI_LINE (EXTI_Line13)
#define USRSW_EXTI_IRQN (EXTI15_10_IRQn)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Falling)
#define USRSW_PRESSED (0)
/* LED */
#define PYB_LED1_PORT (GPIOA)
...
...
stm/boards/PYBOARD4/mpconfigboard.h
View file @
ee31f71d
...
...
@@ -14,14 +14,11 @@
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_AUDIO (0)
#define USRSW_PORT (GPIOB)
#define USRSW_PIN (
GPIO_P
in_3)
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
#define USRSW_PIN (
p
in_
B
3)
#define USRSW_PUPD (GPIO_PuPd_UP)
#define USRSW_EXTI_PIN (EXTI_PinSource3)
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOB)
#define USRSW_EXTI_LINE (EXTI_Line3)
#define USRSW_EXTI_IRQN (EXTI3_IRQn)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Falling)
#define USRSW_PRESSED (0)
/* LED */
#define PYB_LED1_PORT (GPIOA)
...
...
stm/boards/STM32F4DISC/mpconfigboard.h
View file @
ee31f71d
...
...
@@ -14,14 +14,11 @@
#define MICROPY_HW_ENABLE_SERVO (0)
#define MICROPY_HW_ENABLE_AUDIO (0)
#define USRSW_PORT (GPIOA)
#define USRSW_PIN (
GPIO_P
in_0)
// USRSW is pulled low. Pressing the button makes the input go high.
#define USRSW_PIN (
p
in_
A
0)
#define USRSW_PUPD (GPIO_PuPd_NOPULL)
#define USRSW_EXTI_PIN (EXTI_PinSource0)
#define USRSW_EXTI_PORT (EXTI_PortSourceGPIOA)
#define USRSW_EXTI_LINE (EXTI_Line0)
#define USRSW_EXTI_IRQN (EXTI0_IRQn)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Falling)
#define USRSW_EXTI_EDGE (EXTI_Trigger_Rising)
#define USRSW_PRESSED (1)
/* LED */
#define PYB_LED1_PORT (GPIOD)
...
...
stm/boards/make-pins.py
View file @
ee31f71d
...
...
@@ -133,6 +133,13 @@ class Pin(object):
self
.
alt_fn_count
,
self
.
alt_fn_name
()))
print
(
''
)
def
print_header
(
self
,
hdr_file
):
hdr_file
.
write
(
'extern const pin_obj_t pin_{:s};
\n
'
.
format
(
self
.
pin_name
()))
if
self
.
alt_fn_count
>
0
:
hdr_file
.
write
(
'extern const pin_af_obj_t pin_{:s}_af[];
\n
'
.
format
(
self
.
pin_name
()))
class
Pins
(
object
):
...
...
@@ -191,6 +198,12 @@ class Pins(object):
print
(
''
)
self
.
print_named
(
'board'
,
self
.
board_pins
)
def
print_header
(
self
,
hdr_filename
):
with
open
(
hdr_filename
,
'wb'
)
as
hdr_file
:
for
pin
in
self
.
pins
:
if
pin
.
board_name
:
pin
.
print_header
(
hdr_file
)
def
main
():
parser
=
argparse
.
ArgumentParser
(
...
...
@@ -215,6 +228,12 @@ def main():
help
=
"Specifies beginning portion of generated pins file"
,
default
=
"stm32f4xx-prefix.c"
)
parser
.
add_argument
(
"-r"
,
"--hdr"
,
dest
=
"hdr_filename"
,
help
=
"Specifies name of generated pin header file"
,
default
=
"build/pins.h"
)
args
=
parser
.
parse_args
(
sys
.
argv
[
1
:])
pins
=
Pins
()
...
...
@@ -235,6 +254,7 @@ def main():
with
open
(
args
.
prefix_filename
,
'r'
)
as
prefix_file
:
print
(
prefix_file
.
read
())
pins
.
print
()
pins
.
print_header
(
args
.
hdr_filename
)
if
__name__
==
"__main__"
:
...
...
stm/exti.c
0 → 100644
View file @
ee31f71d
#include
<stdio.h>
#include
<stddef.h>
#include
<string.h>
#include
<stm32f4xx.h>
#include
<stm32f4xx_gpio.h>
#include
"misc.h"
#include
"mpconfig.h"
#include
"qstr.h"
#include
"obj.h"
#include
"runtime.h"
#include
"nlr.h"
#include
"pin.h"
#include
"exti.h"
// Usage Model:
//
// There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
// and the remaining 6 are from internal sources.
//
// For lines 0 thru 15, a given line can map to the corresponding line from an
// arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
// line 1 can map to Px1 where x is A, B, C, ...
//
// def callback(line, param):
// print("line =", line, "param =", param)
//
// # Configure the pin as a GPIO input.
// pin = pyb.Pin.board.X1
// pyb.gpio_in(pin, pyb.PULL_UP)
// exti = pyb.Exti(pin, pyb.Exti.MODE_IRQ, pyb.Exti.TRIGGER_RISING, callback, 37)
//
// Now every time a rising edge is seen on the X1 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.
//
// Trying to register 2 callbacks onto the same pin will throw an exception.
//
// If pin is passed as an integer, then it is assumed to map to one of the
// internal interrupt sources, and must be in the range 16 thru 22.
//
// All other pin objects go through the pin mapper to come up with one of the
// gpio pins.
//
// Valid modes are pyb.Exti.MODE_IRQ and pyb.Exti.MODE_EVENT (Only MODE_IRQ
// has been tested. MODE_EVENT has something to do with sleep mode and the
// WFE instruction).
//
// Valid edge triggers are pyb.Exti.TRIGGER_RISING, TRIGGER_FALLING, and TRIGGER_BOTH.
//
// exti.line() will return the line number that pin was mapped to.
// exti.disable() can be use to disable the interrupt associated with a given
// exti object. This could be useful for debouncing.
// exti.enable() enables a disabled interrupt
// exti.swint() will allow the callback to be triggered from software.
//
// pyb.Exti.regs() will dump the values of the EXTI registers.
//
// There is also a C API, so that drivers which require EXTI interrupt lines
// can also use this code. See exti.h for the available functions and
// usrsw.h for an example of using this.
#define EXTI_OFFSET (EXTI_BASE - PERIPH_BASE)
// Macro used to set/clear the bit corresponding to the line in the IMR/EMR
// register in an atomic fashion by using bitband addressing.
#define EXTI_MODE_BB(mode, line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + (mode)) * 32) + ((line) * 4)))
// This macro will work with the EXTI_Trigger_Rising and EXTI_Trigger_Falling constants
// but not EXTI_Trigger_Rising_Falling.
#define EXTI_EDGE_BB(edge, line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + (edge)) * 32) + ((line) * 4)))
#define EXTI_SWIER_BB(line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, SWIER)) * 32) + ((line) * 4)))
#define EXTI_PR_BB(line) (*(vu32 *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, PR)) * 32) + ((line) * 4)))
typedef
struct
{
mp_obj_base_t
base
;
mp_small_int_t
line
;
}
exti_obj_t
;
typedef
struct
{
mp_obj_t
callback_obj
;
mp_obj_t
param_obj
;
EXTIMode_TypeDef
mode
;
}
exti_vector_t
;
static
exti_vector_t
exti_vector
[
EXTI_NUM_VECTORS
];
static
const
uint8_t
nvic_irq_channel
[
EXTI_NUM_VECTORS
]
=
{
EXTI0_IRQn
,
EXTI1_IRQn
,
EXTI2_IRQn
,
EXTI3_IRQn
,
EXTI4_IRQn
,
EXTI9_5_IRQn
,
EXTI9_5_IRQn
,
EXTI9_5_IRQn
,
EXTI9_5_IRQn
,
EXTI9_5_IRQn
,
EXTI15_10_IRQn
,
EXTI15_10_IRQn
,
EXTI15_10_IRQn
,
EXTI15_10_IRQn
,
EXTI15_10_IRQn
,
EXTI15_10_IRQn
,
PVD_IRQn
,
RTC_Alarm_IRQn
,
OTG_FS_WKUP_IRQn
,
ETH_WKUP_IRQn
,
OTG_HS_WKUP_IRQn
,
TAMP_STAMP_IRQn
,
RTC_WKUP_IRQn
};
uint
exti_register
(
mp_obj_t
pin_obj
,
mp_obj_t
mode_obj
,
mp_obj_t
trigger_obj
,
mp_obj_t
callback_obj
,
mp_obj_t
param_obj
)
{
const
pin_obj_t
*
pin
=
NULL
;
uint
v_line
;
if
(
MP_OBJ_IS_INT
(
pin_obj
))
{
// If an integer is passed in, then use it to identify lines 16 thru 22
// We expect lines 0 thru 15 to be passed in as a pin, so that we can
// get both the port number and line number.
v_line
=
mp_obj_get_int
(
pin_obj
);
if
(
v_line
<
16
)
{
nlr_jump
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"EXTI vector %d < 16, use a Pin object"
,
v_line
));
}
if
(
v_line
>=
EXTI_NUM_VECTORS
)
{
nlr_jump
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"EXTI vector %d >= max of %d"
,
v_line
,
EXTI_NUM_VECTORS
));
}
}
else
{
pin
=
pin_map_user_obj
(
pin_obj
);
v_line
=
pin
->
pin
;
}
int
mode
=
mp_obj_get_int
(
mode_obj
);
if
(
!
IS_EXTI_MODE
(
mode
))
{
nlr_jump
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"Invalid EXTI Mode: %d"
,
mode
));
}
int
trigger
=
mp_obj_get_int
(
trigger_obj
);
if
(
!
IS_EXTI_TRIGGER
(
trigger
))
{
nlr_jump
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"Invalid EXTI Trigger: %d"
,
trigger
));
}
exti_vector_t
*
v
=
&
exti_vector
[
v_line
];
if
(
v
->
callback_obj
!=
mp_const_none
&&
callback_obj
!=
mp_const_none
)
{
nlr_jump
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"EXTI vector %d is already in use"
,
v_line
));
}
// We need to update callback and param atomically, so we disable the line
// before we update anything.
exti_disable
(
v_line
);
if
(
pin
&&
callback_obj
)
{
// Enable SYSCFG clock
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_SYSCFG
,
ENABLE
);
// For EXTI lines 0 thru 15, we need to configure which port controls
// the line.
SYSCFG_EXTILineConfig
(
pin
->
port
,
v_line
);
}
v
->
callback_obj
=
callback_obj
;
v
->
param_obj
=
param_obj
;
v
->
mode
=
mode
;
if
(
v
->
callback_obj
!=
mp_const_none
)
{
// The EXTI_Init function isn't atomic. It uses |= and &=.
// We use bit band operations to make it atomic.
exti_disable
(
v_line
);
EXTI_EDGE_BB
(
EXTI_Trigger_Rising
,
v_line
)
=
trigger
==
EXTI_Trigger_Rising
||
trigger
==
EXTI_Trigger_Rising_Falling
;
EXTI_EDGE_BB
(
EXTI_Trigger_Falling
,
v_line
)
=
trigger
==
EXTI_Trigger_Falling
||
trigger
==
EXTI_Trigger_Rising_Falling
;
exti_enable
(
v_line
);
/* Enable and set NVIC Interrupt to the lowest priority */
NVIC_InitTypeDef
NVIC_InitStructure
;
NVIC_InitStructure
.
NVIC_IRQChannel
=
nvic_irq_channel
[
v_line
];
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0x0F
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
0x0F
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
}
return
v_line
;
}
void
exti_enable
(
uint
line
)
{
if
(
line
>=
EXTI_NUM_VECTORS
)
{
return
;
}
// Since manipulating IMR/EMR is a read-modify-write, and we want this to
// be atomic, we use the bit-band area to just affect the bit we're
// interested in.
EXTI_MODE_BB
(
exti_vector
[
line
].
mode
,
line
)
=
1
;
}
void
exti_disable
(
uint
line
)
{
if
(
line
>=
EXTI_NUM_VECTORS
)
{
return
;
}
// Since manipulating IMR/EMR is a read-modify-write, and we want this to
// be atomic, we use the bit-band area to just affect the bit we're
// interested in.
EXTI_MODE_BB
(
EXTI_Mode_Interrupt
,
line
)
=
0
;
EXTI_MODE_BB
(
EXTI_Mode_Event
,
line
)
=
0
;
}
void
exti_swint
(
uint
line
)
{
if
(
line
>=
EXTI_NUM_VECTORS
)
{
return
;
}
EXTI_SWIER_BB
(
line
)
=
1
;
}
static
mp_obj_t
exti_obj_line
(
mp_obj_t
self_in
)
{
exti_obj_t
*
self
=
self_in
;
return
MP_OBJ_NEW_SMALL_INT
(
self
->
line
);
}
static
mp_obj_t
exti_obj_enable
(
mp_obj_t
self_in
)
{
exti_obj_t
*
self
=
self_in
;
exti_enable
(
self
->
line
);
return
mp_const_none
;
}
static
mp_obj_t
exti_obj_disable
(
mp_obj_t
self_in
)
{
exti_obj_t
*
self
=
self_in
;
exti_disable
(
self
->
line
);
return
mp_const_none
;
}
static
mp_obj_t
exti_obj_swint
(
mp_obj_t
self_in
)
{
exti_obj_t
*
self
=
self_in
;
exti_swint
(
self
->
line
);
return
mp_const_none
;
}
static
MP_DEFINE_CONST_FUN_OBJ_1
(
exti_obj_line_obj
,
exti_obj_line
);
static
MP_DEFINE_CONST_FUN_OBJ_1
(
exti_obj_enable_obj
,
exti_obj_enable
);
static
MP_DEFINE_CONST_FUN_OBJ_1
(
exti_obj_disable_obj
,
exti_obj_disable
);
static
MP_DEFINE_CONST_FUN_OBJ_1
(
exti_obj_swint_obj
,
exti_obj_swint
);
static
const
mp_method_t
exti_methods
[]
=
{
{
"line"
,
&
exti_obj_line_obj
},
{
"enable"
,
&
exti_obj_enable_obj
},
{
"disable"
,
&
exti_obj_disable_obj
},
{
"swint"
,
&
exti_obj_swint_obj
},
{
NULL
,
NULL
},
};
static
mp_obj_t
exti_regs
(
void
)
{
printf
(
"EXTI_IMR %08lx
\n
"
,
EXTI
->
IMR
);
printf
(
"EXTI_EMR %08lx
\n
"
,
EXTI
->
EMR
);
printf
(
"EXTI_RTSR %08lx
\n
"
,
EXTI
->
RTSR
);
printf
(
"EXTI_FTSR %08lx
\n
"
,
EXTI
->
FTSR
);
printf
(
"EXTI_SWIER %08lx
\n
"
,
EXTI
->
SWIER
);
printf
(
"EXTI_PR %08lx
\n
"
,
EXTI
->
PR
);
return
mp_const_none
;
}
static
MP_DEFINE_CONST_FUN_OBJ_0
(
exti_regs_obj
,
exti_regs
);
typedef
struct
{
const
char
*
name
;
uint
val
;
}
exti_const_t
;
static
const
exti_const_t
exti_const
[]
=
{
{
"MODE_IRQ"
,
EXTI_Mode_Interrupt
},
{
"MODE_EVENT"
,
EXTI_Mode_Event
},
{
"TRIGGER_RISING"
,
EXTI_Trigger_Rising
},
{
"TRIGGER_FALLING"
,
EXTI_Trigger_Falling
},
{
"TRIGGER_BOTH"
,
EXTI_Trigger_Rising_Falling
},
};
#define EXTI_NUM_CONST (sizeof(exti_const) / sizeof(exti_const[0]))
static
void
exti_load_attr
(
mp_obj_t
self_in
,
qstr
attr_qstr
,
mp_obj_t
*
dest
)
{
(
void
)
self_in
;
const
char
*
attr
=
qstr_str
(
attr_qstr
);
if
(
strcmp
(
attr
,
"regs"
)
==
0
)
{
dest
[
0
]
=
(
mp_obj_t
)
&
exti_regs_obj
;
return
;
}
const
exti_const_t
*
entry
=
&
exti_const
[
0
];
for
(;
entry
<
&
exti_const
[
EXTI_NUM_CONST
];
entry
++
)
{
if
(
strcmp
(
attr
,
entry
->
name
)
==
0
)
{
dest
[
0
]
=
MP_OBJ_NEW_SMALL_INT
(
entry
->
val
);
dest
[
1
]
=
MP_OBJ_NULL
;
return
;
}
}
}
// line_obj = pyb.Exti(pin, mode, trigger, callback, [param])
static
mp_obj_t
exti_call
(
mp_obj_t
type_in
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
// type_in == exti_obj_type
rt_check_nargs
(
n_args
,
4
,
5
,
n_kw
,
0
);
exti_obj_t
*
self
=
m_new_obj
(
exti_obj_t
);
self
->
base
.
type
=
type_in
;
mp_obj_t
line_obj
=
args
[
0
];
mp_obj_t
mode_obj
=
args
[
1
];
mp_obj_t
trigger_obj
=
args
[
2
];
mp_obj_t
callback_obj
=
args
[
3
];
mp_obj_t
param_obj
=
mp_const_none
;
if
(
n_args
>
4
)
{
param_obj
=
args
[
4
];
}
self
->
line
=
exti_register
(
line_obj
,
mode_obj
,
trigger_obj
,
callback_obj
,
param_obj
);
return
self
;
}
static
void
exti_meta_obj_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
self_in
,
mp_print_kind_t
kind
)
{
(
void
)
self_in
;
print
(
env
,
"<Exti meta>"
);
}
static
void
exti_obj_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
self_in
,
mp_print_kind_t
kind
)
{
exti_obj_t
*
self
=
self_in
;
print
(
env
,
"<Exti line=%u>"
,
self
->
line
);
}
static
const
mp_obj_type_t
exti_meta_obj_type
=
{
{
&
mp_type_type
},
.
name
=
MP_QSTR_ExtiMeta
,
.
print
=
exti_meta_obj_print
,
.
call
=
exti_call
,
.
load_attr
=
exti_load_attr
,
};
static
const
mp_obj_type_t
exti_obj_type
=
{
{
&
exti_meta_obj_type
},
.
name
=
MP_QSTR_Exti
,
.
print
=
exti_obj_print
,
.
methods
=
exti_methods
,
};
void
exti_init_early
(
void
)
{
for
(
exti_vector_t
*
v
=
exti_vector
;
v
<
&
exti_vector
[
EXTI_NUM_VECTORS
];
v
++
)
{
v
->
callback_obj
=
mp_const_none
;
v
->
param_obj
=
mp_const_none
;
v
->
mode
=
EXTI_Mode_Interrupt
;
}
}
void
exti_init
(
mp_obj_t
mod
)
{
rt_store_attr
(
mod
,
MP_QSTR_Exti
,
(
mp_obj_t
)
&
exti_obj_type
);
}
static
void
Handle_EXTI_Irq
(
uint32_t
line
)
{
if
(
EXTI_PR_BB
(
line
))
{
EXTI_PR_BB
(
line
)
=
1
;
// Clears bit
if
(
line
<
EXTI_NUM_VECTORS
)
{
exti_vector_t
*
v
=
&
exti_vector
[
line
];
if
(
v
->
callback_obj
!=
mp_const_none
)
{
rt_call_function_2
(
v
->
callback_obj
,
MP_OBJ_NEW_SMALL_INT
(
line
),
v
->
param_obj
);
}
}
}
}
void
EXTI0_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
0
);
}
void
EXTI1_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
1
);
}
void
EXTI2_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
2
);
}
void
EXTI3_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
3
);
}
void
EXTI4_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
4
);
}
void
EXTI9_5_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
5
);
Handle_EXTI_Irq
(
6
);
Handle_EXTI_Irq
(
7
);
Handle_EXTI_Irq
(
8
);
Handle_EXTI_Irq
(
9
);
}
void
EXTI15_10_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
10
);
Handle_EXTI_Irq
(
11
);
Handle_EXTI_Irq
(
12
);
Handle_EXTI_Irq
(
13
);
Handle_EXTI_Irq
(
14
);
Handle_EXTI_Irq
(
15
);
}
void
PVD_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
16
);
}
void
RTC_Alarm_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
17
);
}
#if 0 // dealt with in stm32fxxx_it.c
void OTG_FS_WKUP_IRQHandler(void) {
Handle_EXTI_Irq(18);
}
#endif
void
ETH_WKUP_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
19
);
}
#if 0 // dealt with in stm32fxxx_it.c
void OTG_HS_WKUP_IRQHandler(void) {
Handle_EXTI_Irq(20);
}
#endif
void
TAMP_STAMP_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
21
);
}
void
RTC_WKUP_IRQHandler
(
void
)
{
Handle_EXTI_Irq
(
22
);
}
stm/exti.h
0 → 100644
View file @
ee31f71d
// Vectors 0-15 are for regular pins
// Vectors 16-22 are for internal sources.
//
// Use the following constants for the internal sources:
#define EXTI_PVD_OUTPUT (16)
#define EXTI_RTC_ALARM (17)
#define EXTI_USB_OTG_FS_WAKEUP (18)
#define EXTI_ETH_WAKEUP (19)
#define EXTI_USB_OTG_HS_WAKEUP (20)
#define EXTI_RTC_TIMESTAMP (21)
#define EXTI_RTC_WAKEUP (22)
#define EXTI_NUM_VECTORS 23
void
exti_init_early
(
void
);
void
exti_init
(
mp_obj_t
mod
);
uint
exti_register
(
mp_obj_t
pin_obj
,
mp_obj_t
mode_obj
,
mp_obj_t
trigger_obj
,
mp_obj_t
callback_obj
,
mp_obj_t
param_obj
);
void
exti_enable
(
uint
line
);
void
exti_disable
(
uint
line
);
void
exti_swint
(
uint
line
);
typedef
struct
{
mp_obj_t
callback
;
mp_obj_t
param
;
}
exti_t
;
stm/gpio.h
View file @
ee31f71d
mp_obj_t
pyb_gpio
(
uint
n_args
,
mp_obj_t
*
args
);
mp_obj_t
pyb_gpio_input
(
mp_obj_t
arg_pin
,
mp_obj_t
arg_mode
);
mp_obj_t
pyb_gpio_output
(
mp_obj_t
arg_pin
,
mp_obj_t
arg_mode
);
void
gpio_init
(
mp_obj_t
mod
);
stm/main.c
View file @
ee31f71d
...
...
@@ -51,6 +51,7 @@
#include
"rtc.h"
#include
"file.h"
#include
"pin.h"
#include
"exti.h"
int
errno
;
...
...
@@ -346,9 +347,6 @@ int main(void) {
led_state
(
PYB_LED_G1
,
1
);
// more sub-system init