Minsu Lee / mbed-src

Dependents:   WizFi250_AP_HelloWorld

Fork of mbed-src by DongEun Koak

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) {