Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
c4361227
Commit
c4361227
authored
Feb 26, 2014
by
Damien George
Browse files
Merge pull request #318 from dhylands/exti
Add EXTI support
parents
e7070085
ee31f71d
Changes
13
Hide whitespace changes
Inline
Side-by-side
stm/Makefile
View file @
c4361227
...
...
@@ -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 @
c4361227
...
...
@@ -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 @
c4361227
...
...
@@ -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 @
c4361227
...
...
@@ -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 @
c4361227
...
...
@@ -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 @
c4361227
...
...
@@ -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 @
c4361227
#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 @
c4361227
// 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 @
c4361227
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 @
c4361227
...
...
@@ -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