Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: WizFi250_AP_HelloWorld
Fork of mbed-src by
Diff: targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c
- Revision:
- 340:28d1f895c6fe
- Parent:
- 227:7bd0639b8911
- Child:
- 402:09075a3b15e3
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c Mon Oct 06 11:45:07 2014 +0100
+++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pwmout_api.c Thu Oct 09 08:15:07 2014 +0100
@@ -27,52 +27,60 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
-#include "mbed_assert.h"
#include "pwmout_api.h"
#if DEVICE_PWMOUT
#include "cmsis.h"
#include "pinmap.h"
+#include "mbed_error.h"
// TIM1 cannot be used because already used by the us_ticker
+// Uncomment/comment line above to use an alternate timer,
+// If the channel is not the same,
+// Please don't forget to uncomment/comment in the pwmout_write() function also
static const PinMap PinMap_PWM[] = {
- {PA_4, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_4)}, // TIM14_CH1
- {PA_6, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH1
-// {PA_6, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_5)}, // TIM16_CH1
- {PA_7, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH2
-// {PA_7, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_4)}, // TIM14_CH1
-// {PA_7, TIM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_5)}, // TIM17_CH1
- {PB_0, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH3
- {PB_1, TIM_14, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM14_CH1
-// {PB_1, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH4
- {PB_4, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH1
- {PB_5, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM3_CH2
- {PB_6, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM16_CH1N
- {PB_7, TIM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM17_CH1N
- {PB_8, TIM_16, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM16_CH1
- {PB_9, TIM_17, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_2)}, // TIM17_CH1
- {PB_14, TIM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM15_CH1
- {PB_15, TIM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_1)}, // TIM15_CH2
-// {PB_15, TIM_15, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_3)}, // TIM15_CH1N
- {PC_6, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH1
- {PC_7, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH2
- {PC_8, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH3
- {PC_9, TIM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_NOPULL, GPIO_AF_0)}, // TIM3_CH4
+ {PA_4, PWM_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF4_TIM14)}, // TIM14_CH1
+ {PA_6, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH1
+// {PA_6, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_TIM16)}, // TIM16_CH1
+ {PA_7, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH2
+// {PA_7, PWM_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF4_TIM14)}, // TIM14_CH1
+// {PA_7, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_TIM17)}, // TIM17_CH1
+ {PB_0, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH3
+ {PB_1, PWM_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF0_TIM14)}, // TIM14_CH1
+// {PB_1, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH4
+ {PB_4, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH1
+ {PB_5, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH2
+ {PB_6, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM16)}, // TIM16_CH1N
+ {PB_7, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM17)}, // TIM17_CH1N
+ {PB_8, PWM_16, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM16)}, // TIM16_CH1
+ {PB_9, PWM_17, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF2_TIM17)}, // TIM17_CH1
+ {PB_14, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM15)}, // TIM15_CH1
+ {PB_15, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM15)}, // TIM15_CH2
+// {PB_15, PWM_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF3_TIM15)}, // TIM15_CH1N
+ {PC_6, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH1
+ {PC_7, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH2
+ {PC_8, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH3
+ {PC_9, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF1_TIM3)}, // TIM3_CH4
{NC, NC, 0}
};
+static TIM_HandleTypeDef TimHandle;
+
void pwmout_init(pwmout_t* obj, PinName pin) {
// Get the peripheral name from the pin and assign it to the object
obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
- MBED_ASSERT(obj->pwm != (PWMName)NC);
+
+ if (obj->pwm == (PWMName)NC) {
+ error("PWM error: pinout mapping failed.");
+ }
// Enable TIM clock
- if (obj->pwm == TIM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- if (obj->pwm == TIM_14) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
- if (obj->pwm == TIM_15) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
- if (obj->pwm == TIM_16) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
- if (obj->pwm == TIM_17) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17, ENABLE);
+ if (obj->pwm == PWM_3) __TIM3_CLK_ENABLE();
+ if (obj->pwm == PWM_14) __TIM14_CLK_ENABLE();
+ if (obj->pwm == PWM_15) __TIM15_CLK_ENABLE();
+ if (obj->pwm == PWM_16) __TIM16_CLK_ENABLE();
+ if (obj->pwm == PWM_17) __TIM17_CLK_ENABLE();
// Configure GPIO
pinmap_pinout(pin, PinMap_PWM);
@@ -85,79 +93,82 @@
}
void pwmout_free(pwmout_t* obj) {
- // Configure GPIOs
- pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
+ // Configure GPIO
+ pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
void pwmout_write(pwmout_t* obj, float value) {
- TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
- TIM_OCInitTypeDef TIM_OCInitStructure;
+ TIM_OC_InitTypeDef sConfig;
+ int channel = 0;
+ int complementary_channel = 0;
- if (value < 0.0) {
+ TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
+
+ if (value < (float)0.0) {
value = 0.0;
- } else if (value > 1.0) {
+ } else if (value > (float)1.0) {
value = 1.0;
}
obj->pulse = (uint32_t)((float)obj->period * value);
// Configure channels
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_Pulse = obj->pulse;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_Low;
- TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
- TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
+ sConfig.OCMode = TIM_OCMODE_PWM1;
+ sConfig.Pulse = obj->pulse;
+ sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
+ sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
+ sConfig.OCFastMode = TIM_OCFAST_DISABLE;
+ sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
+ sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
switch (obj->pin) {
// Channels 1
case PA_4:
case PA_6:
+// case PA_7:
case PB_1:
case PB_4:
case PB_8:
case PB_9:
case PB_14:
case PC_6:
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
- TIM_OC1Init(tim, &TIM_OCInitStructure);
+ channel = TIM_CHANNEL_1;
break;
// Channels 1N
case PB_6:
case PB_7:
- TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
- TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
- TIM_OC1Init(tim, &TIM_OCInitStructure);
+// case PB_15:
+ channel = TIM_CHANNEL_1;
+ complementary_channel = 1;
break;
// Channels 2
- case PA_7:
+ case PA_7:
case PB_5:
+ case PB_15:
case PC_7:
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
- TIM_OC2Init(tim, &TIM_OCInitStructure);
+ channel = TIM_CHANNEL_2;
break;
// Channels 3
case PB_0:
case PC_8:
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
- TIM_OC3Init(tim, &TIM_OCInitStructure);
+ channel = TIM_CHANNEL_3;
break;
// Channels 4
// case PB_1:
case PC_9:
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
- TIM_OC4Init(tim, &TIM_OCInitStructure);
+ channel = TIM_CHANNEL_4;
break;
default:
return;
}
- TIM_CtrlPWMOutputs(tim, ENABLE);
+ HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel);
+ if (complementary_channel) {
+ HAL_TIMEx_PWMN_Start(&TimHandle, channel);
+ } else {
+ HAL_TIM_PWM_Start(&TimHandle, channel);
+ }
}
float pwmout_read(pwmout_t* obj) {
@@ -165,7 +176,7 @@
if (obj->period > 0) {
value = (float)(obj->pulse) / (float)(obj->period);
}
- return ((value > 1.0) ? (1.0) : (value));
+ return ((value > (float)1.0) ? (float)(1.0) : (value));
}
void pwmout_period(pwmout_t* obj, float seconds) {
@@ -177,26 +188,28 @@
}
void pwmout_period_us(pwmout_t* obj, int us) {
- TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+ TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
+
float dc = pwmout_read(obj);
- TIM_Cmd(tim, DISABLE);
+ __HAL_TIM_DISABLE(&TimHandle);
- obj->period = us;
+ // Update the SystemCoreClock variable
+ SystemCoreClockUpdate();
- TIM_TimeBaseStructure.TIM_Period = obj->period - 1;
- TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
+ TimHandle.Init.Period = us - 1;
+ TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
+ TimHandle.Init.ClockDivision = 0;
+ TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
+ HAL_TIM_PWM_Init(&TimHandle);
// Set duty cycle again
pwmout_write(obj, dc);
- TIM_ARRPreloadConfig(tim, ENABLE);
+ // Save for future use
+ obj->period = us;
- TIM_Cmd(tim, ENABLE);
+ __HAL_TIM_ENABLE(&TimHandle);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
