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
1dc2862a
Commit
1dc2862a
authored
May 13, 2016
by
Damien George
Browse files
stmhal/led: Allow LEDs to be in PWM mode with TIM1 and channels 1-4.
This allows PYBv3 to use PWM for LED(1) and LED(2).
parent
68a7a92c
Changes
6
Hide whitespace changes
Inline
Side-by-side
stmhal/boards/PYBLITEV10/mpconfigboard.h
View file @
1dc2862a
...
...
@@ -71,8 +71,8 @@
#define MICROPY_HW_LED2 (pin_A14) // green
#define MICROPY_HW_LED3 (pin_A15) // yellow
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, GPIO_AF2_TIM3 }
#define MICROPY_HW_LED3_PWM { TIM2, 2,
TIM_CHANNEL_1,
GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3,
TIM_CHANNEL_1,
GPIO_AF2_TIM3 }
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
...
...
stmhal/boards/PYBV10/mpconfigboard.h
View file @
1dc2862a
...
...
@@ -82,8 +82,8 @@
#define MICROPY_HW_LED2 (pin_A14) // green
#define MICROPY_HW_LED3 (pin_A15) // yellow
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, GPIO_AF2_TIM3 }
#define MICROPY_HW_LED3_PWM { TIM2, 2,
TIM_CHANNEL_1,
GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3,
TIM_CHANNEL_1,
GPIO_AF2_TIM3 }
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
...
...
stmhal/boards/PYBV11/mpconfigboard.h
View file @
1dc2862a
...
...
@@ -82,8 +82,8 @@
#define MICROPY_HW_LED2 (pin_A14) // green
#define MICROPY_HW_LED3 (pin_A15) // yellow
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, GPIO_AF2_TIM3 }
#define MICROPY_HW_LED3_PWM { TIM2, 2,
TIM_CHANNEL_1,
GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3,
TIM_CHANNEL_1,
GPIO_AF2_TIM3 }
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
...
...
stmhal/boards/PYBV3/mpconfigboard.h
View file @
1dc2862a
...
...
@@ -66,10 +66,13 @@
#define MICROPY_HW_USRSW_PRESSED (0)
// LEDs
#define MICROPY_HW_LED_INVERTED (1) // LEDs are on when pin is driven low
#define MICROPY_HW_LED1 (pin_A8) // R1 - red
#define MICROPY_HW_LED2 (pin_A10) // R2 - red
#define MICROPY_HW_LED3 (pin_C4) // G1 - green
#define MICROPY_HW_LED4 (pin_C5) // G2 - green
#define MICROPY_HW_LED1_PWM { TIM1, 1, TIM_CHANNEL_1, GPIO_AF1_TIM1 }
#define MICROPY_HW_LED2_PWM { TIM1, 1, TIM_CHANNEL_3, GPIO_AF1_TIM1 }
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRH = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRL = pin->pin_mask)
...
...
stmhal/boards/PYBV4/mpconfigboard.h
View file @
1dc2862a
...
...
@@ -79,8 +79,8 @@
#define MICROPY_HW_LED2 (pin_A14) // green
#define MICROPY_HW_LED3 (pin_A15) // yellow
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, GPIO_AF2_TIM3 }
#define MICROPY_HW_LED3_PWM { TIM2, 2,
TIM_CHANNEL_1,
GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3,
TIM_CHANNEL_1,
GPIO_AF2_TIM3 }
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
...
...
stmhal/led.c
View file @
1dc2862a
...
...
@@ -41,6 +41,11 @@
///
/// The LED object controls an individual LED (Light Emitting Diode).
// the default is that LEDs are not inverted, and pin driven high turns them on
#ifndef MICROPY_HW_LED_INVERTED
#define MICROPY_HW_LED_INVERTED (0)
#endif
typedef
struct
_pyb_led_obj_t
{
mp_obj_base_t
base
;
mp_uint_t
led_id
;
...
...
@@ -86,30 +91,34 @@ void led_init(void) {
|| defined(MICROPY_HW_LED4_PWM)
// The following is semi-generic code to control LEDs using PWM.
// It currently supports TIM2 and TIM3, channel 1
only
.
// It currently supports
TIM1,
TIM2 and TIM3, channel
s
1
-4
.
// Configure by defining the relevant MICROPY_HW_LEDx_PWM macros in mpconfigboard.h.
// If they are not defined then PWM will not be available for that LED.
#define LED_PWM_ENABLED (1)
#ifndef MICROPY_HW_LED1_PWM
#define MICROPY_HW_LED1_PWM { NULL, 0, 0 }
#define MICROPY_HW_LED1_PWM { NULL, 0,
0,
0 }
#endif
#ifndef MICROPY_HW_LED2_PWM
#define MICROPY_HW_LED2_PWM { NULL, 0, 0 }
#define MICROPY_HW_LED2_PWM { NULL, 0,
0,
0 }
#endif
#ifndef MICROPY_HW_LED3_PWM
#define MICROPY_HW_LED3_PWM { NULL, 0, 0 }
#define MICROPY_HW_LED3_PWM { NULL, 0,
0,
0 }
#endif
#ifndef MICROPY_HW_LED4_PWM
#define MICROPY_HW_LED4_PWM { NULL, 0, 0 }
#define MICROPY_HW_LED4_PWM { NULL, 0,
0,
0 }
#endif
#define LED_PWM_TIM_PERIOD (10000) // TIM runs at 1MHz and fires every 10ms
// this gives the address of the CCR register for channels 1-4
#define LED_PWM_CCR(pwm_cfg) ((volatile uint32_t*)&(pwm_cfg)->tim->CCR1 + ((pwm_cfg)->tim_channel >> 2))
typedef
struct
_led_pwm_config_t
{
TIM_TypeDef
*
tim
;
uint8_t
tim_id
;
uint8_t
tim_channel
;
uint8_t
alt_func
;
}
led_pwm_config_t
;
...
...
@@ -143,6 +152,7 @@ STATIC void led_pwm_init(int led) {
// TIM configuration
switch
(
pwm_cfg
->
tim_id
)
{
case
1
:
__TIM1_CLK_ENABLE
();
break
;
case
2
:
__TIM2_CLK_ENABLE
();
break
;
case
3
:
__TIM3_CLK_ENABLE
();
break
;
default:
assert
(
0
);
...
...
@@ -153,21 +163,20 @@ STATIC void led_pwm_init(int led) {
tim
.
Init
.
Prescaler
=
timer_get_source_freq
(
pwm_cfg
->
tim_id
)
/
1000000
-
1
;
// TIM runs at 1MHz
tim
.
Init
.
ClockDivision
=
TIM_CLOCKDIVISION_DIV1
;
tim
.
Init
.
CounterMode
=
TIM_COUNTERMODE_UP
;
tim
.
Init
.
RepetitionCounter
=
0
;
HAL_TIM_PWM_Init
(
&
tim
);
// PWM configuration
(only channel 1 supported at the moment)
// PWM configuration
TIM_OC_InitTypeDef
oc_init
;
oc_init
.
OCMode
=
TIM_OCMODE_PWM1
;
oc_init
.
Pulse
=
0
;
// off
oc_init
.
OCPolarity
=
TIM_OCPOLARITY_HIGH
;
oc_init
.
OCPolarity
=
MICROPY_HW_LED_INVERTED
?
TIM_OCPOLARITY_LOW
:
TIM_OCPOLARITY_HIGH
;
oc_init
.
OCFastMode
=
TIM_OCFAST_DISABLE
;
/* needed only for TIM1 and TIM8
oc_init.OCNPolarity = TIM_OCNPOLARITY_HIGH;
oc_init.OCIdleState = TIM_OCIDLESTATE_SET;
oc_init.OCNIdleState = TIM_OCNIDLESTATE_SET;
*/
HAL_TIM_PWM_ConfigChannel
(
&
tim
,
&
oc_init
,
TIM_CHANNEL_1
);
HAL_TIM_PWM_Start
(
&
tim
,
TIM_CHANNEL_1
);
oc_init
.
OCNPolarity
=
TIM_OCNPOLARITY_HIGH
;
// needed for TIM1 and TIM8
oc_init
.
OCIdleState
=
TIM_OCIDLESTATE_SET
;
// needed for TIM1 and TIM8
oc_init
.
OCNIdleState
=
TIM_OCNIDLESTATE_SET
;
// needed for TIM1 and TIM8
HAL_TIM_PWM_ConfigChannel
(
&
tim
,
&
oc_init
,
pwm_cfg
->
tim_channel
);
HAL_TIM_PWM_Start
(
&
tim
,
pwm_cfg
->
tim_channel
);
// indicate that this LED is using PWM
led_pwm_state
|=
1
<<
led
;
...
...
@@ -236,8 +245,8 @@ int led_get_intensity(pyb_led_t led) {
#if LED_PWM_ENABLED
if
(
led_pwm_is_enabled
(
led
))
{
TIM_TypeDef
*
tim
=
led_pwm_config
[
led
-
1
]
.
tim
;
mp_uint_t
i
=
(
tim
->
CCR1
*
255
+
LED_PWM_TIM_PERIOD
-
2
)
/
(
LED_PWM_TIM_PERIOD
-
1
);
const
led_pwm_config_t
*
pwm_cfg
=
&
led_pwm_config
[
led
-
1
];
mp_uint_t
i
=
(
*
LED_PWM_CCR
(
pwm_cfg
)
*
255
+
LED_PWM_TIM_PERIOD
-
2
)
/
(
LED_PWM_TIM_PERIOD
-
1
);
if
(
i
>
255
)
{
i
=
255
;
}
...
...
@@ -248,26 +257,25 @@ int led_get_intensity(pyb_led_t led) {
const
pin_obj_t
*
led_pin
=
pyb_led_obj
[
led
-
1
].
led_pin
;
GPIO_TypeDef
*
gpio
=
led_pin
->
gpio
;
// TODO convert high/low to on/off depending on board
if
(
gpio
->
ODR
&
led_pin
->
pin_mask
)
{
// pin is high
return
255
;
return
MICROPY_HW_LED_INVERTED
?
0
:
255
;
}
else
{
// pin is low
return
0
;
return
MICROPY_HW_LED_INVERTED
?
255
:
0
;
}
}
void
led_set_intensity
(
pyb_led_t
led
,
mp_int_t
intensity
)
{
#if LED_PWM_ENABLED
if
(
intensity
>
0
&&
intensity
<
255
)
{
TIM_TypeDef
*
tim
=
led_pwm_config
[
led
-
1
]
.
tim
;
if
(
tim
!=
NULL
)
{
const
led_pwm_config_t
*
pwm_cfg
=
&
led_pwm_config
[
led
-
1
];
if
(
pwm_cfg
->
tim
!=
NULL
)
{
// set intensity using PWM pulse width
if
(
!
led_pwm_is_enabled
(
led
))
{
led_pwm_init
(
led
);
}
tim
->
CCR1
=
intensity
*
(
LED_PWM_TIM_PERIOD
-
1
)
/
255
;
*
LED_PWM_CCR
(
pwm_cfg
)
=
intensity
*
(
LED_PWM_TIM_PERIOD
-
1
)
/
255
;
return
;
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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