Merge pull request #2103 from LMESTM/fix_pwmout_period

Fix pwmout period
pull/2162/merge
Martin Kojtal 2016-07-15 10:26:08 +01:00 committed by GitHub
commit 46057c5d70
63 changed files with 708 additions and 456 deletions

View File

@ -93,13 +93,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -88,13 +88,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -88,13 +88,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -88,18 +88,12 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -88,13 +88,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -93,18 +93,12 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -93,18 +93,12 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,57 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -75,6 +75,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -101,7 +102,7 @@ void pwmout_write(pwmout_t* obj, float value) {
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCFastMode = TIM_OCFAST_DISABLE;
@ -265,18 +266,39 @@ void pwmout_period_us(pwmout_t* obj, int us) {
// Update the SystemCoreClock variable // Update the SystemCoreClock variable
SystemCoreClockUpdate(); SystemCoreClockUpdate();
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick * pwm unit = 1us, period/pulse can be from 1us to 65535us
* or
* pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
* Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
TimHandle.Init.Prescaler = ((SystemCoreClock / 1000000) * obj->prescaler) - 1;
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&TimHandle);
// Set duty cycle again if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
pwmout_write(obj, dc); error("Cannot initialize PWM");
}
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }

View File

@ -89,19 +89,13 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "gpio_object.h" #include "gpio_object.h"
#include "common_objects.h"
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -89,13 +89,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -89,18 +89,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,57 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -58,6 +58,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -86,7 +87,7 @@ void pwmout_write(pwmout_t* obj, float value)
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCFastMode = TIM_OCFAST_DISABLE;
@ -193,18 +194,37 @@ void pwmout_period_us(pwmout_t* obj, int us)
// Update the SystemCoreClock variable // Update the SystemCoreClock variable
SystemCoreClockUpdate(); SystemCoreClockUpdate();
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick * pwm unit = 1us, period/pulse can be from 1us to 65535us
* or
* pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
* Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
TimHandle.Init.Prescaler = ((SystemCoreClock / 1000000) * obj->prescaler) - 1;
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&TimHandle); HAL_TIM_PWM_Init(&TimHandle);
// Set duty cycle again
pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }

View File

@ -96,16 +96,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -96,16 +96,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -96,21 +96,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -96,21 +96,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -96,21 +96,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -96,21 +96,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -69,6 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -188,12 +189,12 @@ void pwmout_period_us(pwmout_t* obj, int us)
error("Cannot initialize PWM"); error("Cannot initialize PWM");
} }
// Set duty cycle again
pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }

View File

@ -95,15 +95,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -102,20 +102,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; // Used by irq int index; // Used by irq
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,15 +90,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,20 +95,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,20 +95,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,15 +90,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,15 +90,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,15 +90,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -90,15 +90,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,21 +95,13 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "gpio_object.h" #include "gpio_object.h"
#include "common_objects.h"
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -95,20 +95,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,20 +95,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -94,6 +94,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -121,7 +122,7 @@ void pwmout_write(pwmout_t* obj, float value)
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCFastMode = TIM_OCFAST_DISABLE;
@ -240,26 +241,45 @@ void pwmout_period_us(pwmout_t* obj, int us)
default: default:
return; return;
} }
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
* pwm unit = 1us, period/pulse can be from 1us to 65535us
* or
* pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
* Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
// TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
if (APBxCLKDivider == RCC_HCLK_DIV1) if (APBxCLKDivider == RCC_HCLK_DIV1)
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 us tick TimHandle.Init.Prescaler = (uint16_t)(((PclkFreq) / 1000000) * obj->prescaler) - 1; // 1 us tick
else else
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 us tick TimHandle.Init.Prescaler = (uint16_t)(((PclkFreq * 2) / 1000000) * obj->prescaler) - 1; // 1 us tick
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) { if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
error("Cannot initialize PWM\n"); error("Cannot initialize PWM\n");
} }
// Set duty cycle again
pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }
@ -276,6 +296,7 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
void pwmout_pulsewidth_us(pwmout_t* obj, int us) void pwmout_pulsewidth_us(pwmout_t* obj, int us)
{ {
float value = (float)us / (float)obj->period; float value = (float)us / (float)obj->period;
printf("pwmout_pulsewidth_us: period=%d, us=%d, dc=%d%%\r\n", obj->period, us, (int) (value*100));
pwmout_write(obj, value); pwmout_write(obj, value);
} }

View File

@ -96,20 +96,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -101,20 +101,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -101,16 +101,8 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#include "common_objects.h"
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -69,6 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -96,7 +97,7 @@ void pwmout_write(pwmout_t* obj, float value)
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCFastMode = TIM_OCFAST_DISABLE;
@ -192,12 +193,31 @@ void pwmout_period_us(pwmout_t* obj, int us)
return; return;
} }
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
* pwm unit = 1us, period/pulse can be from 1us to 65535us
* or
* pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
* Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
// TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
if (APBxCLKDivider == RCC_HCLK_DIV1) if (APBxCLKDivider == RCC_HCLK_DIV1)
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 µs tick TimHandle.Init.Prescaler = (uint16_t)(((PclkFreq) / 1000000) * obj->prescaler) - 1; // 1 us tick
else else
TimHandle.Init.Prescaler = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 µs tick TimHandle.Init.Prescaler = (uint16_t)(((PclkFreq * 2) / 1000000) * obj->prescaler) - 1; // 1 us tick
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
@ -205,12 +225,12 @@ void pwmout_period_us(pwmout_t* obj, int us)
error("Cannot initialize PWM\n"); error("Cannot initialize PWM\n");
} }
// Set duty cycle again
pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }

View File

@ -95,15 +95,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -89,15 +89,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -89,15 +89,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -95,15 +95,7 @@ struct i2c_s {
I2CName i2c; I2CName i2c;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -66,6 +66,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -93,7 +94,7 @@ void pwmout_write(pwmout_t* obj, float value)
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_ENABLE; sConfig.OCFastMode = TIM_OCFAST_ENABLE;
@ -148,8 +149,26 @@ void pwmout_period_us(pwmout_t* obj, int us)
__HAL_TIM_DISABLE(&TimHandle); __HAL_TIM_DISABLE(&TimHandle);
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick * pwm unit = 1us, period/pulse can be from 1us to 65535us
* or
* pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
* Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
TimHandle.Init.Prescaler = ((SystemCoreClock / 1000000) * obj->prescaler) - 1;
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
@ -157,12 +176,12 @@ void pwmout_period_us(pwmout_t* obj, int us)
error("Cannot initialize PWM"); error("Cannot initialize PWM");
} }
// Set duty cycle again
pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }

View File

@ -94,13 +94,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -94,13 +94,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -94,13 +94,7 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s { #include "common_objects.h"
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,57 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -62,6 +62,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -89,7 +90,7 @@ void pwmout_write(pwmout_t* obj, float value)
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_ENABLE; sConfig.OCFastMode = TIM_OCFAST_ENABLE;
@ -167,18 +168,39 @@ void pwmout_period_us(pwmout_t* obj, int us)
SystemCoreClockUpdate(); SystemCoreClockUpdate();
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick * pwm unit = 1us, period/pulse can be from 1us to 65535us
* or
* pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
* Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
TimHandle.Init.Prescaler = ((SystemCoreClock / 1000000) * obj->prescaler) - 1;
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_PWM_Init(&TimHandle);
// Set duty cycle again if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
pwmout_write(obj, dc); error("Cannot initialize PWM");
}
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }

View File

@ -96,21 +96,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -101,21 +101,13 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "gpio_object.h" #include "gpio_object.h"
#include "common_objects.h"
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -101,20 +101,12 @@ struct i2c_s {
uint32_t slave; uint32_t slave;
}; };
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t period;
uint32_t pulse;
uint32_t channel;
uint32_t inverted;
};
struct can_s { struct can_s {
CANName can; CANName can;
int index; int index;
}; };
#include "common_objects.h"
#include "gpio_object.h" #include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,59 @@
/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2016, STMicroelectronics
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef MBED_COMMON_OBJECTS_H
#define MBED_COMMON_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pwmout_s {
PWMName pwm;
PinName pin;
uint32_t prescaler;
uint32_t period;
uint32_t pulse;
uint8_t channel;
uint8_t inverted;
};
#include "gpio_object.h"
#ifdef __cplusplus
}
#endif
#endif

View File

@ -77,6 +77,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
obj->prescaler = 1;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
@ -104,7 +105,7 @@ void pwmout_write(pwmout_t* obj, float value)
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse / obj->prescaler;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_ENABLE; sConfig.OCFastMode = TIM_OCFAST_ENABLE;
@ -168,22 +169,39 @@ void pwmout_period_us(pwmout_t* obj, int us)
SystemCoreClockUpdate(); SystemCoreClockUpdate();
TimHandle.Init.Period = us - 1; /* To make it simple, we use to possible prescaler values which lead to:
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick * pwm unit = 1us, period/pulse can be from 1us to 65535us
TimHandle.Init.ClockDivision = 0; * or
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
TimHandle.Init.RepetitionCounter = 0; * Be careful that all the channels of a PWM shares the same prescaler
*/
if (us > 0xFFFF) {
obj->prescaler = 500;
} else {
obj->prescaler = 1;
}
TimHandle.Init.Prescaler = ((SystemCoreClock / 1000000) * obj->prescaler) - 1;
if (TimHandle.Init.Prescaler > 0xFFFF)
error("PWM: out of range prescaler");
TimHandle.Init.Period = (us - 1) / obj->prescaler;
if (TimHandle.Init.Period > 0xFFFF)
error("PWM: out of range period");
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) { if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
error("Cannot initialize PWM\n"); error("Cannot initialize PWM\n");
} }
// Set duty cycle again
pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
// Set duty cycle again
pwmout_write(obj, dc);
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }