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
3fafe730
Commit
3fafe730
authored
Sep 25, 2014
by
Damien George
Browse files
Merge pull request #868 from dhylands/fix-teensy-float
Add pulse_width_percent to teensy.
parents
52b5d76a
53d5fa64
Changes
6
Hide whitespace changes
Inline
Side-by-side
stmhal/qstrdefsport.h
View file @
3fafe730
...
...
@@ -175,7 +175,7 @@ Q(BOTH)
// for TimerChannel class
Q
(
TimerChannel
)
Q
(
pulse_width
)
Q
(
pulse_width_
ratio
)
Q
(
pulse_width_
percent
)
Q
(
compare
)
Q
(
capture
)
Q
(
polarity
)
...
...
stmhal/timer.c
View file @
3fafe730
...
...
@@ -276,8 +276,8 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void
}
else
{
print
(
env
,
"Timer(%u, prescaler=%u, period=%u, mode=%s, div=%u)"
,
self
->
tim_id
,
self
->
tim
.
In
it
.
Prescaler
,
self
->
tim
.
Init
.
Period
,
self
->
tim
.
In
stance
->
PSC
&
0xffff
,
__HAL_TIM_GetAutoreload
(
&
self
->
tim
)
&
TIMER_CNT_MASK
(
self
)
,
self
->
tim
.
Init
.
CounterMode
==
TIM_COUNTERMODE_UP
?
"UP"
:
self
->
tim
.
Init
.
CounterMode
==
TIM_COUNTERMODE_DOWN
?
"DOWN"
:
"CENTER"
,
self
->
tim
.
Init
.
ClockDivision
==
TIM_CLOCKDIVISION_DIV4
?
4
:
...
...
@@ -543,7 +543,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit);
/// Keyword arguments for Timer.PWM modes:
///
/// - `pulse_width` - determines the initial pulse width value to use.
/// - `pulse_width_
ratio
` - determines the initial pulse width
ratio
to use.
/// - `pulse_width_
percent
` - determines the initial pulse width
percentage
to use.
///
/// Keyword arguments for Timer.OC modes:
///
...
...
@@ -566,12 +566,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit);
/// ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=210000)
/// ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=420000)
STATIC
const
mp_arg_t
pyb_timer_channel_args
[]
=
{
{
MP_QSTR_callback
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pin
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pulse_width
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
{
MP_QSTR_pulse_width_
ratio
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_compare
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_polarity
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
{
MP_QSTR_callback
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pin
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pulse_width
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
{
MP_QSTR_pulse_width_
percent
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_compare
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_polarity
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
};
#define PYB_TIMER_CHANNEL_NUM_ARGS MP_ARRAY_SIZE(pyb_timer_channel_args)
...
...
@@ -667,9 +667,17 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *args, mp_map
// absolute pulse width value given
oc_config
.
Pulse
=
vals
[
2
].
u_int
;
}
else
if
(
vals
[
3
].
u_obj
!=
mp_const_none
)
{
// pulse width
ratio
given
// pulse width
percent
given
uint32_t
period
=
(
__HAL_TIM_GetAutoreload
(
&
self
->
tim
)
&
TIMER_CNT_MASK
(
self
))
+
1
;
uint32_t
cmp
=
mp_obj_get_float
(
vals
[
3
].
u_obj
)
*
period
;
uint32_t
cmp
;
#if MICROPY_PY_BUILTINS_FLOAT
if
(
MP_OBJ_IS_TYPE
(
vals
[
3
].
u_obj
,
&
mp_type_float
))
{
cmp
=
mp_obj_get_float
(
vals
[
3
].
u_obj
)
*
period
/
100
.
0
;
}
else
#endif
{
cmp
=
mp_obj_get_int
(
vals
[
3
].
u_obj
)
*
period
/
100
;
}
if
(
cmp
<
0
)
{
cmp
=
0
;
}
else
if
(
cmp
>
period
)
{
...
...
@@ -891,9 +899,6 @@ STATIC void pyb_timer_channel_print(void (*print)(void *env, const char *fmt, ..
/// pulse_width is the logical name to use when the channel is in PWM mode.
STATIC
mp_obj_t
pyb_timer_channel_capture_compare
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_channel_obj_t
*
self
=
args
[
0
];
if
(
self
->
channel
==
0
)
{
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"Timer %d no channel specified"
,
self
->
timer
->
tim_id
));
}
if
(
n_args
==
1
)
{
// get
return
mp_obj_new_int
(
__HAL_TIM_GetCompare
(
&
self
->
timer
->
tim
,
TIMER_CHANNEL
(
self
))
&
TIMER_CNT_MASK
(
self
->
timer
));
...
...
@@ -910,19 +915,28 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_capture_compare_obj
/// a floating-point number between 0.0 and 1.0, and is relative to the period
/// of the timer associated with this channel. For example, a ratio of 0.5
/// would be a 50% duty cycle.
STATIC
mp_obj_t
pyb_timer_channel_pulse_width_
ratio
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
)
{
STATIC
mp_obj_t
pyb_timer_channel_pulse_width_
percent
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_channel_obj_t
*
self
=
args
[
0
];
if
(
self
->
channel
==
0
)
{
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"Timer %d no channel specified"
,
self
->
timer
->
tim_id
));
}
uint32_t
period
=
(
__HAL_TIM_GetAutoreload
(
&
self
->
timer
->
tim
)
&
TIMER_CNT_MASK
(
self
->
timer
))
+
1
;
if
(
n_args
==
1
)
{
// get
uint32_t
cmp
=
__HAL_TIM_GetCompare
(
&
self
->
timer
->
tim
,
TIMER_CHANNEL
(
self
))
&
TIMER_CNT_MASK
(
self
->
timer
);
return
mp_obj_new_float
((
float
)
cmp
/
(
float
)
period
);
#if MICROPY_PY_BUILTINS_FLOAT
return
mp_obj_new_float
((
float
)
cmp
*
100
.
0
/
(
float
)
period
);
#else
return
mp_obj_new_int
(
cmp
*
100
/
period
);
#endif
}
else
{
// set
uint32_t
cmp
=
mp_obj_get_float
(
args
[
1
])
*
period
;
uint32_t
cmp
;
#if MICROPY_PY_BUILTINS_FLOAT
if
(
MP_OBJ_IS_TYPE
(
args
[
1
],
&
mp_type_float
))
{
cmp
=
mp_obj_get_float
(
args
[
1
])
*
period
/
100
.
0
;
}
else
#endif
{
cmp
=
mp_obj_get_int
(
args
[
1
])
*
period
/
100
;
}
if
(
cmp
<
0
)
{
cmp
=
0
;
}
else
if
(
cmp
>
period
)
{
...
...
@@ -932,7 +946,7 @@ STATIC mp_obj_t pyb_timer_channel_pulse_width_ratio(mp_uint_t n_args, const mp_o
return
mp_const_none
;
}
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
pyb_timer_channel_pulse_width_
ratio
_obj
,
1
,
2
,
pyb_timer_channel_pulse_width_
ratio
);
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
pyb_timer_channel_pulse_width_
percent
_obj
,
1
,
2
,
pyb_timer_channel_pulse_width_
percent
);
/// \method callback(fun)
/// Set the function to be called when the timer channel triggers.
...
...
@@ -976,7 +990,7 @@ STATIC const mp_map_elem_t pyb_timer_channel_locals_dict_table[] = {
// instance methods
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_callback
),
(
mp_obj_t
)
&
pyb_timer_channel_callback_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pulse_width
),
(
mp_obj_t
)
&
pyb_timer_channel_capture_compare_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pulse_width_
ratio
),
(
mp_obj_t
)
&
pyb_timer_channel_pulse_width_
ratio
_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pulse_width_
percent
),
(
mp_obj_t
)
&
pyb_timer_channel_pulse_width_
percent
_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_capture
),
(
mp_obj_t
)
&
pyb_timer_channel_capture_compare_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_compare
),
(
mp_obj_t
)
&
pyb_timer_channel_capture_compare_obj
},
};
...
...
teensy/Makefile
View file @
3fafe730
...
...
@@ -6,10 +6,28 @@ QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
# include py core make definitions
include
../py/py.mk
# If you set USE_ARDUINO_TOOLCHAIN=1 then this makefile will attempt to use
# the toolchain that comes with Teensyduino
ifeq
($(USE_ARDUINO_TOOLCHAIN),)
USE_ARDUINO_TOOLCHAIN
=
0
endif
ifeq
($(USE_ARDUINO_TOOLCHAIN),1)
ifeq
($(ARDUINO),)
$(error
USE_ARDUINO_TOOLCHAIN
requires
that
ARDUINO
be
set)
endif
endif
ifeq
($(USE_ARDUINO_TOOLCHAIN),1)
$(info
Using
ARDUINO
toolchain)
CROSS_COMPILE
=
$(ARDUINO)
/hardware/tools/arm-none-eabi/bin/arm-none-eabi-
else
$(info
Using
toolchain
from
PATH)
CROSS_COMPILE
=
arm-none-eabi-
endif
CFLAGS_TEENSY
=
-DF_CPU
=
96000000
-DUSB_SERIAL
-D__MK20DX256__
CFLAGS_CORTEX_M4
=
-mthumb
-mtune
=
cortex-m4
-mcpu
=
cortex-m4
-fsingle-precision-constant
-Wdouble-promotion
$(CFLAGS_TEENSY)
CFLAGS_CORTEX_M4
=
-mthumb
-mtune
=
cortex-m4
-mcpu
=
cortex-m4
-msoft-float
-mfloat-abi
=
soft
-fsingle-precision-constant
-Wdouble-promotion
$(CFLAGS_TEENSY)
INC
=
-I
.
INC
+=
-I
$(PY_SRC)
...
...
@@ -18,11 +36,21 @@ INC += -I$(BUILD)
INC
+=
-Icore
CFLAGS
=
$(INC)
-Wall
-ansi
-std
=
gnu99
-nostdlib
$(CFLAGS_CORTEX_M4)
LDFLAGS
=
-nostdlib
-T
mk20dx256.ld
LDFLAGS
=
-nostdlib
-T
mk20dx256.ld
-msoft-float
-mfloat-abi
=
soft
ifeq
($(USE_ARDUINO_TOOLCHAIN),1)
LIBGCC_FILE_NAME
=
$(
shell
$(CC)
-print-libgcc-file-name
)
LIBM_FILE_NAME
=
$(
shell
$(CC)
-print-file-name
=
libm.a
)
LIBC_FILE_NAME
=
$(
shell
$(CC)
-print-file-name
=
libc.a
)
LIBGCC_FILE_NAME
=
$(ARDUINO)
/hardware/tools/arm-none-eabi/lib/gcc/arm-none-eabi/4.7.2/thumb2/libgcc.a
LIBM_FILE_NAME
=
$(ARDUINO)
/hardware/tools/arm-none-eabi/arm-none-eabi/lib/thumb2/libm.a
LIBC_FILE_NAME
=
$(ARDUINO)
/hardware/tools/arm-none-eabi/arm-none-eabi/lib/thumb2/libc.a
else
LIBGCC_FILE_NAME
=
$(
shell
$(CC)
$(CFLAGS)
-print-libgcc-file-name
)
LIBM_FILE_NAME
=
$(
shell
$(CC)
$(CFLAGS)
-print-file-name
=
libm.a
)
LIBC_FILE_NAME
=
$(
shell
$(CC)
$(CFLAGS)
-print-file-name
=
libc.a
)
endif
#$(info %%%%% LIBGCC_FILE_NAME = $(LIBGCC_FILE_NAME))
#$(info %%%%% LIBM_FILE_NAME = $(LIBM_FILE_NAME))
...
...
teensy/qstrdefsport.h
View file @
3fafe730
...
...
@@ -119,6 +119,7 @@ Q(BOTH)
// for TimerChannel class
Q
(
TimerChannel
)
Q
(
pulse_width
)
Q
(
pulse_width_percent
)
Q
(
compare
)
Q
(
capture
)
Q
(
polarity
)
...
...
teensy/timer.c
View file @
3fafe730
...
...
@@ -42,7 +42,6 @@
#include
"timer.h"
typedef
enum
{
CHANNEL_MODE_PWM_NORMAL
,
CHANNEL_MODE_PWM_INVERTED
,
...
...
@@ -58,7 +57,7 @@ typedef enum {
STATIC
const
struct
{
qstr
name
;
uint32_t
oc_mode
;
}
gC
hannel
M
ode
[]
=
{
}
c
hannel
_m
ode
_info
[]
=
{
{
MP_QSTR_PWM
,
FTM_OCMODE_PWM1
},
{
MP_QSTR_PWM_INVERTED
,
FTM_OCMODE_PWM2
},
{
MP_QSTR_OC_TIMING
,
FTM_OCMODE_TIMING
},
...
...
@@ -127,6 +126,8 @@ mp_uint_t get_prescaler_shift(mp_int_t prescaler) {
/******************************************************************************/
/* Micro Python bindings */
STATIC
const
mp_obj_type_t
pyb_timer_channel_type
;
STATIC
void
pyb_timer_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
self_in
,
mp_print_kind_t
kind
)
{
pyb_timer_obj_t
*
self
=
self_in
;
...
...
@@ -135,8 +136,8 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void
}
else
{
print
(
env
,
"Timer(%u, prescaler=%u, period=%u, mode=%s)"
,
self
->
tim_id
,
1
<<
self
->
ftm
.
In
it
.
PrescalerShift
,
self
->
ftm
.
In
it
.
Period
,
1
<<
(
self
->
ftm
.
In
stance
->
SC
&
7
)
,
self
->
ftm
.
In
stance
->
MOD
&
0xffff
,
self
->
ftm
.
Init
.
CounterMode
==
FTM_COUNTERMODE_UP
?
"tUP"
:
"CENTER"
);
}
}
...
...
@@ -243,7 +244,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, uint n_args, const
/// Construct a new timer object of the given id. If additional
/// arguments are given, then the timer is initialised by `init(...)`.
/// `id` can be 1 to 14, excluding 3.
STATIC
mp_obj_t
pyb_timer_make_new
(
mp_obj_t
type_in
,
uint
n_args
,
uint
n_kw
,
const
mp_obj_t
*
args
)
{
STATIC
mp_obj_t
pyb_timer_make_new
(
mp_obj_t
type_in
,
mp_
uint
_t
n_args
,
mp_
uint
_t
n_kw
,
const
mp_obj_t
*
args
)
{
// check arguments
mp_arg_check_num
(
n_args
,
n_kw
,
1
,
MP_OBJ_FUN_ARGS_MAX
,
true
);
...
...
@@ -280,7 +281,7 @@ STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, uint n_args, uint n_kw, con
return
(
mp_obj_t
)
tim
;
}
STATIC
mp_obj_t
pyb_timer_init
(
uint
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
STATIC
mp_obj_t
pyb_timer_init
(
mp_
uint
_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
return
pyb_timer_init_helper
(
args
[
0
],
n_args
-
1
,
args
+
1
,
kw_args
);
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_KW
(
pyb_timer_init_obj
,
1
,
pyb_timer_init
);
...
...
@@ -289,11 +290,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_init_obj, 1, pyb_timer_init);
/// Deinitialises the timer.
///
/// Disables the callback (and the associated irq).
/// Disables any channel callbacks (and the associated irq).
/// Stops the timer, and disables the timer peripheral.
STATIC
mp_obj_t
pyb_timer_deinit
(
mp_obj_t
self_in
)
{
pyb_timer_obj_t
*
self
=
self_in
;
// Disable the interrupt
// Disable the
base
interrupt
pyb_timer_callback
(
self_in
,
mp_const_none
);
pyb_timer_channel_obj_t
*
chan
=
self
->
channel
;
...
...
@@ -312,10 +314,10 @@ STATIC mp_obj_t pyb_timer_deinit(mp_obj_t self_in) {
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_1
(
pyb_timer_deinit_obj
,
pyb_timer_deinit
);
/// \method channel(channel, ...)
/// \method channel(channel,
mode,
...)
///
/// If only a channel nu
n
ber is passed, then a previously initialized channel
/// object is returned.
/// If only a channel nu
m
ber is passed, then a previously initialized channel
/// object is returned
(or `None` if there is no previous channel)
.
///
/// Othwerwise, a TimerChannel object is initialized and returned.
///
...
...
@@ -345,7 +347,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit);
///
/// Keyword arguments for Timer.PWM modes:
///
/// - 'pulse_width' - determines the initial pulse width to use.
/// - `pulse_width` - determines the initial pulse width value to use.
/// - `pulse_width_percent` - determines the initial pulse width percentage to use.
///
/// Keyword arguments for Timer.OC modes:
///
...
...
@@ -368,17 +371,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit);
/// ch0 = t0.channel(0, pyb.Timer.PWM, pin=pyb.Pin.board.D22, pulse_width=(t0.period() + 1) // 4)
/// ch1 = t0.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.D23, pulse_width=(t0.period() + 1) // 2)
STATIC
const
mp_arg_t
pyb_timer_channel_args
[]
=
{
{
MP_QSTR_callback
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pin
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pulse_width
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_compare
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_polarity
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
{
MP_QSTR_callback
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pin
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_pulse_width
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
{
MP_QSTR_pulse_width_percent
,
MP_ARG_KW_ONLY
|
MP_ARG_OBJ
,
{.
u_obj
=
mp_const_none
}
},
{
MP_QSTR_compare
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0
}
},
{
MP_QSTR_polarity
,
MP_ARG_KW_ONLY
|
MP_ARG_INT
,
{.
u_int
=
0xffffffff
}
},
};
#define PYB_TIMER_CHANNEL_NUM_ARGS MP_ARRAY_SIZE(pyb_timer_channel_args)
STATIC
mp_obj_t
pyb_timer_channel
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
,
mp_map_t
*
kw_args
)
{
mp_arg_check_num
(
n_args
,
n_args
-
2
,
2
,
MP_OBJ_FUN_ARGS_MAX
,
true
);
pyb_timer_obj_t
*
self
=
args
[
0
];
mp_int_t
channel
=
mp_obj_get_int
(
args
[
1
]);
...
...
@@ -396,8 +398,10 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *args, mp_map
prev_chan
=
chan
;
chan
=
chan
->
next
;
}
if
(
kw_args
->
used
==
0
)
{
// Return the previously allocated channel
// If only the channel number is given return the previously allocated
// channel (or None if no previous channel).
if
(
n_args
==
2
)
{
if
(
chan
)
{
return
chan
;
}
...
...
@@ -463,8 +467,32 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *args, mp_map
case
CHANNEL_MODE_PWM_NORMAL
:
case
CHANNEL_MODE_PWM_INVERTED
:
{
FTM_OC_InitTypeDef
oc_config
;
oc_config
.
OCMode
=
gChannelMode
[
chan
->
mode
].
oc_mode
;
oc_config
.
Pulse
=
vals
[
2
].
u_int
;
oc_config
.
OCMode
=
channel_mode_info
[
chan
->
mode
].
oc_mode
;
if
(
vals
[
2
].
u_int
!=
0xffffffff
)
{
// absolute pulse width value given
oc_config
.
Pulse
=
vals
[
2
].
u_int
;
}
else
if
(
vals
[
3
].
u_obj
!=
mp_const_none
)
{
// pulse width ratio given
uint32_t
period
=
(
self
->
ftm
.
Instance
->
MOD
&
0xffff
)
+
1
;
uint32_t
cmp
;
#if MICROPY_PY_BUILTINS_FLOAT
if
(
MP_OBJ_IS_TYPE
(
vals
[
3
].
u_obj
,
&
mp_type_float
))
{
cmp
=
mp_obj_get_float
(
vals
[
3
].
u_obj
)
*
period
/
100
.
0
;
}
else
#endif
{
cmp
=
mp_obj_get_int
(
vals
[
3
].
u_obj
)
*
period
/
100
;
}
if
(
cmp
<
0
)
{
cmp
=
0
;
}
else
if
(
cmp
>
period
)
{
cmp
=
period
;
}
oc_config
.
Pulse
=
cmp
;
}
else
{
// nothing given, default to pulse width of 0
oc_config
.
Pulse
=
0
;
}
oc_config
.
OCPolarity
=
FTM_OCPOLARITY_HIGH
;
HAL_FTM_PWM_ConfigChannel
(
&
self
->
ftm
,
&
oc_config
,
channel
);
...
...
@@ -481,9 +509,9 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *args, mp_map
case
CHANNEL_MODE_OC_INACTIVE
:
case
CHANNEL_MODE_OC_TOGGLE
:
{
FTM_OC_InitTypeDef
oc_config
;
oc_config
.
OCMode
=
gC
hannel
M
ode
[
chan
->
mode
].
oc_mode
;
oc_config
.
Pulse
=
vals
[
3
].
u_int
;
oc_config
.
OCPolarity
=
vals
[
4
].
u_int
;
oc_config
.
OCMode
=
c
hannel
_m
ode
_info
[
chan
->
mode
].
oc_mode
;
oc_config
.
Pulse
=
vals
[
4
].
u_int
;
oc_config
.
OCPolarity
=
vals
[
5
].
u_int
;
if
(
oc_config
.
OCPolarity
==
0xffffffff
)
{
oc_config
.
OCPolarity
=
FTM_OCPOLARITY_HIGH
;
}
...
...
@@ -503,7 +531,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *args, mp_map
case
CHANNEL_MODE_IC
:
{
FTM_IC_InitTypeDef
ic_config
;
ic_config
.
ICPolarity
=
vals
[
4
].
u_int
;
ic_config
.
ICPolarity
=
vals
[
5
].
u_int
;
if
(
ic_config
.
ICPolarity
==
0xffffffff
)
{
ic_config
.
ICPolarity
=
FTM_ICPOLARITY_RISING
;
}
...
...
@@ -523,13 +551,14 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *args, mp_map
default:
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"Invalid mode (%d)"
,
chan
->
mode
));
}
return
chan
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_KW
(
pyb_timer_channel_obj
,
3
,
pyb_timer_channel
);
STATIC
MP_DEFINE_CONST_FUN_OBJ_KW
(
pyb_timer_channel_obj
,
2
,
pyb_timer_channel
);
/// \method counter([value])
/// Get or set the timer counter.
mp_obj_t
pyb_timer_counter
(
uint
n_args
,
const
mp_obj_t
*
args
)
{
STATIC
mp_obj_t
pyb_timer_counter
(
mp_
uint
_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_obj_t
*
self
=
args
[
0
];
if
(
n_args
==
1
)
{
// get
...
...
@@ -544,7 +573,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_counter_obj, 1, 2, pyb_time
/// \method prescaler([value])
/// Get or set the prescaler for the timer.
mp_obj_t
pyb_timer_prescaler
(
uint
n_args
,
const
mp_obj_t
*
args
)
{
STATIC
mp_obj_t
pyb_timer_prescaler
(
mp_
uint
_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_obj_t
*
self
=
args
[
0
];
if
(
n_args
==
1
)
{
// get
...
...
@@ -565,7 +594,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_prescaler_obj, 1, 2, pyb_ti
/// \method period([value])
/// Get or set the period of the timer.
mp_obj_t
pyb_timer_period
(
uint
n_args
,
const
mp_obj_t
*
args
)
{
STATIC
mp_obj_t
pyb_timer_period
(
mp_
uint
_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_obj_t
*
self
=
args
[
0
];
if
(
n_args
==
1
)
{
// get
...
...
@@ -663,7 +692,6 @@ STATIC const mp_map_elem_t pyb_timer_locals_dict_table[] = {
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_FALLING
),
MP_OBJ_NEW_SMALL_INT
(
FTM_ICPOLARITY_FALLING
)
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_BOTH
),
MP_OBJ_NEW_SMALL_INT
(
FTM_ICPOLARITY_BOTH
)
},
};
STATIC
MP_DEFINE_CONST_DICT
(
pyb_timer_locals_dict
,
pyb_timer_locals_dict_table
);
const
mp_obj_type_t
pyb_timer_type
=
{
...
...
@@ -683,10 +711,10 @@ const mp_obj_type_t pyb_timer_type = {
STATIC
void
pyb_timer_channel_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
self_in
,
mp_print_kind_t
kind
)
{
pyb_timer_channel_obj_t
*
self
=
self_in
;
print
(
env
,
"TimerChannel(timer=%u, channel=%u mode=%s)"
,
print
(
env
,
"TimerChannel(timer=%u, channel=%u
,
mode=%s)"
,
self
->
timer
->
tim_id
,
self
->
channel
,
qstr_str
(
gC
hannel
M
ode
[
self
->
mode
].
name
));
qstr_str
(
c
hannel
_m
ode
_info
[
self
->
mode
].
name
));
}
/// \method capture([value])
...
...
@@ -703,25 +731,61 @@ STATIC void pyb_timer_channel_print(void (*print)(void *env, const char *fmt, ..
/// Get or set the pulse width value associated with a channel.
/// capture, compare, and pulse_width are all aliases for the same function.
/// pulse_width is the logical name to use when the channel is in PWM mode.
STATIC
mp_obj_t
pyb_timer_channel_capture_compare
(
uint
n_args
,
const
mp_obj_t
*
args
)
{
STATIC
mp_obj_t
pyb_timer_channel_capture_compare
(
mp_
uint
_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_channel_obj_t
*
self
=
args
[
0
];
if
(
self
->
channel
==
0xffffffff
)
{
nlr_raise
(
mp_obj_new_exception_msg_varg
(
&
mp_type_ValueError
,
"Timer %d no channel specified"
,
self
->
timer
->
tim_id
));
}
FTM_TypeDef
*
FTMx
=
self
->
timer
->
ftm
.
Instance
;
if
(
n_args
==
1
)
{
// get
return
mp_obj_new_int
(
FTMx
->
channel
[
self
->
channel
].
CV
);
return
mp_obj_new_int
(
FTMx
->
channel
[
self
->
channel
].
CV
&
0xffff
);
}
mp_int_t
pw
=
mp_obj_get_int
(
args
[
1
]);
// set
FTMx
->
channel
[
self
->
channel
].
CV
=
pw
;
FTMx
->
channel
[
self
->
channel
].
CV
=
pw
&
0xffff
;
return
mp_const_none
;
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
pyb_timer_channel_capture_compare_obj
,
1
,
2
,
pyb_timer_channel_capture_compare
);
/// \method pulse_width_percent([value])
/// Get or set the pulse width ratio associated with a channel. The value is
/// a floating-point number between 0.0 and 1.0, and is relative to the period
/// of the timer associated with this channel. For example, a ratio of 0.5
/// would be a 50% duty cycle.
STATIC
mp_obj_t
pyb_timer_channel_pulse_width_percent
(
mp_uint_t
n_args
,
const
mp_obj_t
*
args
)
{
pyb_timer_channel_obj_t
*
self
=
args
[
0
];
FTM_TypeDef
*
FTMx
=
self
->
timer
->
ftm
.
Instance
;
uint32_t
period
=
(
FTMx
->
MOD
&
0xffff
)
+
1
;
if
(
n_args
==
1
)
{
// get
uint32_t
cmp
=
FTMx
->
channel
[
self
->
channel
].
CV
&
0xffff
;
#if MICROPY_PY_BUILTINS_FLOAT
return
mp_obj_new_float
((
float
)
cmp
*
100
.
0
/
(
float
)
period
);
#else
return
mp_obj_new_int
(
cmp
*
100
/
period
);
#endif
}
else
{
// set
uint32_t
cmp
;
#if MICROPY_PY_BUILTINS_FLOAT
if
(
MP_OBJ_IS_TYPE
(
args
[
1
],
&
mp_type_float
))
{
cmp
=
mp_obj_get_float
(
args
[
1
])
*
period
/
100
.
0
;
}
else
#endif
{
cmp
=
mp_obj_get_int
(
args
[
1
])
*
period
/
100
;
}
if
(
cmp
<
0
)
{
cmp
=
0
;
}
else
if
(
cmp
>
period
)
{
cmp
=
period
;
}
FTMx
->
channel
[
self
->
channel
].
CV
=
cmp
&
0xffff
;
return
mp_const_none
;
}
}
STATIC
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
pyb_timer_channel_pulse_width_percent_obj
,
1
,
2
,
pyb_timer_channel_pulse_width_percent
);
/// \method callback(fun)
/// Set the function to be called when the timer channel triggers.
/// `fun` is passed 1 argument, the timer object.
...
...
@@ -777,6 +841,7 @@ STATIC const mp_map_elem_t pyb_timer_channel_locals_dict_table[] = {
// instance methods
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_callback
),
(
mp_obj_t
)
&
pyb_timer_channel_callback_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pulse_width
),
(
mp_obj_t
)
&
pyb_timer_channel_capture_compare_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pulse_width_percent
),
(
mp_obj_t
)
&
pyb_timer_channel_pulse_width_percent_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_capture
),
(
mp_obj_t
)
&
pyb_timer_channel_capture_compare_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_compare
),
(
mp_obj_t
)
&
pyb_timer_channel_capture_compare_obj
},
#if MICROPY_TIMER_REG
...
...
@@ -785,7 +850,7 @@ STATIC const mp_map_elem_t pyb_timer_channel_locals_dict_table[] = {
};
STATIC
MP_DEFINE_CONST_DICT
(
pyb_timer_channel_locals_dict
,
pyb_timer_channel_locals_dict_table
);
const
mp_obj_type_t
pyb_timer_channel_type
=
{
STATIC
const
mp_obj_type_t
pyb_timer_channel_type
=
{
{
&
mp_type_type
},
.
name
=
MP_QSTR_TimerChannel
,
.
print
=
pyb_timer_channel_print
,
...
...
teensy/timer.h
View file @
3fafe730
...
...
@@ -25,7 +25,6 @@
*/
extern
const
mp_obj_type_t
pyb_timer_type
;
extern
const
mp_obj_type_t
pyb_timer_channel_type
;
void
timer_init0
(
void
);
void
timer_deinit
(
void
);
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment