pwm driver hal'd
This commit is contained in:
parent
bec6f26366
commit
f2bfac4795
15
.cproject
15
.cproject
@ -146,7 +146,6 @@
|
|||||||
<buildTargets>
|
<buildTargets>
|
||||||
<target name="all" path="software/source/test/firmware/kernel/list" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="all" path="software/source/test/firmware/kernel/list" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>all</buildTarget>
|
<buildTarget>all</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -154,7 +153,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="clean" path="software/source/test/firmware/kernel/list" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="clean" path="software/source/test/firmware/kernel/list" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -162,6 +160,7 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="distclean" path="software/source" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="distclean" path="software/source" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments/>
|
||||||
<buildTarget>distclean</buildTarget>
|
<buildTarget>distclean</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
@ -217,7 +216,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="all" path="software/test/firmware/kernel/list" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="all" path="software/test/firmware/kernel/list" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>all</buildTarget>
|
<buildTarget>all</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -249,7 +247,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="distclean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="distclean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>distclean</buildTarget>
|
<buildTarget>distclean</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -287,6 +284,14 @@
|
|||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>true</runAllBuilders>
|
<runAllBuilders>true</runAllBuilders>
|
||||||
</target>
|
</target>
|
||||||
|
<target name="pwm test" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments>TEST_APP=pwm BOARD=stm32f4-discovery DEBUG=y</buildArguments>
|
||||||
|
<buildTarget>test</buildTarget>
|
||||||
|
<stopOnError>true</stopOnError>
|
||||||
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
|
<runAllBuilders>true</runAllBuilders>
|
||||||
|
</target>
|
||||||
<target name="msp430-ccrf example_radio_rx all" path="software/source/test" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="msp430-ccrf example_radio_rx all" path="software/source/test" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments>APP=example_radio_rx BOARD=msp430-ccrf DEBUG=y</buildArguments>
|
<buildArguments>APP=example_radio_rx BOARD=msp430-ccrf DEBUG=y</buildArguments>
|
||||||
@ -313,7 +318,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="all" path="software/source/test/firmware/kernel/ringbuffer" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="all" path="software/source/test/firmware/kernel/ringbuffer" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>all</buildTarget>
|
<buildTarget>all</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
@ -321,7 +325,6 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="clean" path="software/source/test/firmware/kernel/ringbuffer" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
<target name="clean" path="software/source/test/firmware/kernel/ringbuffer" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
<buildCommand>make</buildCommand>
|
<buildCommand>make</buildCommand>
|
||||||
<buildArguments/>
|
|
||||||
<buildTarget>clean</buildTarget>
|
<buildTarget>clean</buildTarget>
|
||||||
<stopOnError>true</stopOnError>
|
<stopOnError>true</stopOnError>
|
||||||
<useDefaultCommand>true</useDefaultCommand>
|
<useDefaultCommand>true</useDefaultCommand>
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#if 0
|
|
||||||
#include "../../../driver/include/stm32f4_pwm.h"
|
|
||||||
#include "pwm.h"
|
|
||||||
#endif
|
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#include "pwm.h"
|
||||||
|
#include "stm32f4_pwm.h"
|
||||||
|
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "stm32f4_uart.h"
|
#include "stm32f4_uart.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include "stm32f4_gpio.h"
|
#include "stm32f4_gpio.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
// GPIO_D12
|
// GPIO_D12
|
||||||
static const GPIO_InitTypeDef port_cfg_d12 = {
|
static const GPIO_InitTypeDef port_cfg_d12 = {
|
||||||
.Pin = GPIO_PIN_12,
|
.Pin = GPIO_PIN_12,
|
||||||
@ -48,7 +49,7 @@ static const struct driver gpio_d12 = {
|
|||||||
DRIVER_TYPE_GPIO,
|
DRIVER_TYPE_GPIO,
|
||||||
&__gpio_d12,
|
&__gpio_d12,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// SYSTEM TICK
|
// SYSTEM TICK
|
||||||
static const enum stm32_sys_tick_time_base stm23_sys_tick_time_base =
|
static const enum stm32_sys_tick_time_base stm23_sys_tick_time_base =
|
||||||
@ -65,46 +66,47 @@ static const struct loki_timer timer_1 = {
|
|||||||
.fp = &timer_fp
|
.fp = &timer_fp
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
// PWM CHANNEL 4
|
// PWM CHANNEL 4
|
||||||
/* apb1 clock = 84MHz */
|
/* apb1 clock = 84MHz */
|
||||||
/* period_reg = src_clk / presc / cnt_clk */
|
/* period_reg = src_clk / presc / cnt_clk */
|
||||||
/* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */
|
/* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */
|
||||||
static const TIM_TimeBaseInitTypeDef timer_4_cfg = {
|
static TIM_HandleTypeDef tim4_handle = {
|
||||||
.TIM_RepetitionCounter = 0x0000,
|
.Instance = TIM4,
|
||||||
.TIM_Prescaler = 0,
|
.Init.Prescaler = 0,
|
||||||
.TIM_ClockDivision = TIM_CKD_DIV1,
|
.Init.CounterMode = TIM_COUNTERMODE_UP,
|
||||||
.TIM_CounterMode = TIM_CounterMode_Up,
|
.Init.Period = 4199,
|
||||||
.TIM_Period = 4199
|
.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1,
|
||||||
|
.Init.RepetitionCounter = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TIM_OCInitTypeDef t4_output_compare_cfg = {
|
static TIM_OC_InitTypeDef t4_output_compare_cfg = {
|
||||||
.TIM_OutputNState = TIM_OutputNState_Disable,
|
.OCMode = TIM_OCMODE_PWM1,
|
||||||
.TIM_OCNPolarity = TIM_OCPolarity_High,
|
.Pulse = 0,
|
||||||
.TIM_OCIdleState = TIM_OCIdleState_Reset,
|
.OCPolarity = TIM_OCPOLARITY_HIGH,
|
||||||
.TIM_OCNIdleState = TIM_OCNIdleState_Set,
|
.OCNPolarity = TIM_OCNPOLARITY_HIGH,
|
||||||
.TIM_OCMode = TIM_OCMode_PWM1,
|
.OCFastMode = TIM_OCFAST_DISABLE,
|
||||||
.TIM_OCPolarity = TIM_OCPolarity_High,
|
.OCIdleState = TIM_OCIDLESTATE_SET,
|
||||||
.TIM_OutputState = TIM_OutputState_Enable,
|
.OCNIdleState = TIM_OCNIDLESTATE_SET
|
||||||
.TIM_Pulse = 0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const GPIO_InitTypeDef port_cfg_D15 = {
|
static const GPIO_InitTypeDef port_cfg_D15 = {
|
||||||
.GPIO_Pin = GPIO_Pin_15,
|
.Pin = GPIO_PIN_15,
|
||||||
.GPIO_Mode = GPIO_Mode_AF,
|
.Mode = GPIO_MODE_AF_PP,
|
||||||
.GPIO_OType = GPIO_OType_PP,
|
.Speed = GPIO_SPEED_FREQ_HIGH,
|
||||||
.GPIO_PuPd = GPIO_PuPd_UP,
|
.Pull = GPIO_PULLUP,
|
||||||
.GPIO_Speed = GPIO_Speed_100MHz,
|
.Alternate = GPIO_AF2_TIM4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct stm32f4_gpio t4c4_gpio = {
|
||||||
|
.port = GPIOD,
|
||||||
|
.pin = &port_cfg_D15,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct stm32f4_pwm str32f4_pwm_4 = {
|
static struct stm32f4_pwm str32f4_pwm_4 = {
|
||||||
.timer = TIM4,
|
.pwm_gpio = &t4c4_gpio,
|
||||||
.timer_cfg = &timer_4_cfg,
|
.timer_handle = &tim4_handle,
|
||||||
.output_compare_cfg = &t4_output_compare_cfg,
|
.output_compare_cfg = &t4_output_compare_cfg,
|
||||||
.port = GPIOD,
|
.channel = TIM_CHANNEL_4,
|
||||||
.pin_src = GPIO_PinSource15,
|
|
||||||
.port_cfg = &port_cfg_D15,
|
|
||||||
.channel = channel_4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pwm pwm_ch4 = {
|
static const struct pwm pwm_ch4 = {
|
||||||
@ -120,25 +122,25 @@ const struct driver pwm_4 = {
|
|||||||
DRIVER_TYPE_PWM,
|
DRIVER_TYPE_PWM,
|
||||||
&pwm_ch4,
|
&pwm_ch4,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
// PWM Channel 3
|
// PWM Channel 3
|
||||||
static const GPIO_InitTypeDef port_cfg_D14 = {
|
static const GPIO_InitTypeDef port_cfg_D14 = {
|
||||||
.GPIO_Pin = GPIO_Pin_14,
|
.Pin = GPIO_PIN_14,
|
||||||
.GPIO_Mode = GPIO_Mode_AF,
|
.Mode = GPIO_MODE_AF_PP,
|
||||||
.GPIO_OType = GPIO_OType_PP,
|
.Speed = GPIO_SPEED_FREQ_HIGH,
|
||||||
.GPIO_PuPd = GPIO_PuPd_UP,
|
.Pull = GPIO_PULLUP,
|
||||||
.GPIO_Speed = GPIO_Speed_100MHz,
|
.Alternate = GPIO_AF2_TIM4,
|
||||||
|
};
|
||||||
|
static const struct stm32f4_gpio stm32f4_pwm_t4c3_gpio = {
|
||||||
|
.port = GPIOD,
|
||||||
|
.pin = &port_cfg_D14,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct stm32f4_pwm str32f4_pwm_3 = {
|
static struct stm32f4_pwm str32f4_pwm_3 = {
|
||||||
.timer = TIM4,
|
.pwm_gpio = &stm32f4_pwm_t4c3_gpio,
|
||||||
.timer_cfg = &timer_4_cfg,
|
.timer_handle = &tim4_handle,
|
||||||
.output_compare_cfg = &t4_output_compare_cfg,
|
.output_compare_cfg = &t4_output_compare_cfg,
|
||||||
.port = GPIOD,
|
.channel = TIM_CHANNEL_3,
|
||||||
.pin_src = GPIO_PinSource14,
|
|
||||||
.port_cfg = &port_cfg_D14,
|
|
||||||
.channel = channel_3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pwm pwm_ch3 = {
|
static const struct pwm pwm_ch3 = {
|
||||||
@ -154,25 +156,25 @@ const struct driver pwm_3 = {
|
|||||||
DRIVER_TYPE_PWM,
|
DRIVER_TYPE_PWM,
|
||||||
&pwm_ch3,
|
&pwm_ch3,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
// PWM Channel 2
|
// PWM Channel 2
|
||||||
static const GPIO_InitTypeDef port_cfg_D13 = {
|
static const GPIO_InitTypeDef port_cfg_D13 = {
|
||||||
.GPIO_Pin = GPIO_Pin_13,
|
.Pin = GPIO_PIN_13,
|
||||||
.GPIO_Mode = GPIO_Mode_AF,
|
.Mode = GPIO_MODE_AF_PP,
|
||||||
.GPIO_OType = GPIO_OType_PP,
|
.Speed = GPIO_SPEED_FREQ_HIGH,
|
||||||
.GPIO_PuPd = GPIO_PuPd_UP,
|
.Pull = GPIO_PULLUP,
|
||||||
.GPIO_Speed = GPIO_Speed_100MHz,
|
.Alternate = GPIO_AF2_TIM4,
|
||||||
|
};
|
||||||
|
static const struct stm32f4_gpio stm32f4_pwm_t4c2_gpio = {
|
||||||
|
.port = GPIOD,
|
||||||
|
.pin = &port_cfg_D13,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct stm32f4_pwm str32f4_pwm_2 = {
|
static struct stm32f4_pwm str32f4_pwm_2 = {
|
||||||
.timer = TIM4,
|
.pwm_gpio = &stm32f4_pwm_t4c2_gpio,
|
||||||
.timer_cfg = &timer_4_cfg,
|
.timer_handle = &tim4_handle,
|
||||||
.output_compare_cfg = &t4_output_compare_cfg,
|
.output_compare_cfg = &t4_output_compare_cfg,
|
||||||
.port = GPIOD,
|
.channel = TIM_CHANNEL_2,
|
||||||
.pin_src = GPIO_PinSource13,
|
|
||||||
.port_cfg = &port_cfg_D13,
|
|
||||||
.channel = channel_2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pwm pwm_ch2 = {
|
static const struct pwm pwm_ch2 = {
|
||||||
@ -188,25 +190,25 @@ const struct driver pwm_2 = {
|
|||||||
DRIVER_TYPE_PWM,
|
DRIVER_TYPE_PWM,
|
||||||
&pwm_ch2,
|
&pwm_ch2,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
// PWM Channel 1
|
// PWM Channel 1
|
||||||
static const GPIO_InitTypeDef port_cfg_D12 = {
|
static const GPIO_InitTypeDef port_cfg_D12 = {
|
||||||
.GPIO_Pin = GPIO_Pin_12,
|
.Pin = GPIO_PIN_12,
|
||||||
.GPIO_Mode = GPIO_Mode_AF,
|
.Mode = GPIO_MODE_AF_PP,
|
||||||
.GPIO_OType = GPIO_OType_PP,
|
.Speed = GPIO_SPEED_FREQ_HIGH,
|
||||||
.GPIO_PuPd = GPIO_PuPd_UP,
|
.Pull = GPIO_PULLUP,
|
||||||
.GPIO_Speed = GPIO_Speed_100MHz,
|
.Alternate = GPIO_AF2_TIM4,
|
||||||
|
};
|
||||||
|
static const struct stm32f4_gpio stm32f4_pwm_t4c1_gpio = {
|
||||||
|
.port = GPIOD,
|
||||||
|
.pin = &port_cfg_D12,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct stm32f4_pwm str32f4_pwm_1 = {
|
static struct stm32f4_pwm str32f4_pwm_1 = {
|
||||||
.timer = TIM4,
|
.pwm_gpio = &stm32f4_pwm_t4c1_gpio,
|
||||||
.timer_cfg = &timer_4_cfg,
|
.timer_handle = &tim4_handle,
|
||||||
.output_compare_cfg = &t4_output_compare_cfg,
|
.output_compare_cfg = &t4_output_compare_cfg,
|
||||||
.port = GPIOD,
|
.channel = TIM_CHANNEL_1,
|
||||||
.pin_src = GPIO_PinSource12,
|
|
||||||
.port_cfg = &port_cfg_D12,
|
|
||||||
.channel = channel_1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pwm pwm_ch1 = {
|
static const struct pwm pwm_ch1 = {
|
||||||
@ -222,7 +224,7 @@ const struct driver pwm_1 = {
|
|||||||
DRIVER_TYPE_PWM,
|
DRIVER_TYPE_PWM,
|
||||||
&pwm_ch1,
|
&pwm_ch1,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
// UART 1
|
// UART 1
|
||||||
static const GPIO_InitTypeDef port_cfg_uart1 = {
|
static const GPIO_InitTypeDef port_cfg_uart1 = {
|
||||||
.Pin = GPIO_PIN_6 | GPIO_PIN_7,
|
.Pin = GPIO_PIN_6 | GPIO_PIN_7,
|
||||||
|
32
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
32
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* stm32f4_pwm.h
|
||||||
|
*
|
||||||
|
* Created on: Aug 9, 2016
|
||||||
|
* Author: tkl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_
|
||||||
|
#define SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
struct stm32f4_pwm {
|
||||||
|
const struct stm32f4_gpio *pwm_gpio;
|
||||||
|
TIM_HandleTypeDef *timer_handle;
|
||||||
|
TIM_OC_InitTypeDef *output_compare_cfg;
|
||||||
|
uint32_t channel;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
|
int stm32f4_pwm_open(const void *pwm);
|
||||||
|
int stm32f4_pwm_close(const void *pwm);
|
||||||
|
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent);
|
||||||
|
|
||||||
|
static const struct pwm_fp stm32f4_pwm_fp = {
|
||||||
|
.open = stm32f4_pwm_open,
|
||||||
|
.close = stm32f4_pwm_close,
|
||||||
|
.set_duty_cycle = stm32f4_pwm_set_duty_cycle,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ */
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* stm32f4_pwm.c
|
|
||||||
*
|
|
||||||
* Created on: Aug 9, 2016
|
|
||||||
* Author: tkl
|
|
||||||
*/
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "stm32f4xx.h"
|
|
||||||
|
|
||||||
#include "pwm.h"
|
|
||||||
#include "stm32f4_pwm.h"
|
|
||||||
|
|
||||||
struct stm32f4_pwm_object {
|
|
||||||
uint8_t used_channels;
|
|
||||||
uint32_t channel_1_max_period;
|
|
||||||
uint32_t channel_2_max_period;
|
|
||||||
uint32_t channel_3_max_period;
|
|
||||||
uint32_t channel_4_max_period;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct stm32f4_pwm_object stm32f4_pwm_object = {
|
|
||||||
.used_channels = 0,
|
|
||||||
.channel_1_max_period = 0,
|
|
||||||
.channel_2_max_period = 0,
|
|
||||||
.channel_3_max_period = 0,
|
|
||||||
.channel_4_max_period = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
int stm32f4_pwm_open(const void *pwm)
|
|
||||||
{
|
|
||||||
if(NULL == pwm)
|
|
||||||
return -1;
|
|
||||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
|
||||||
uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0;
|
|
||||||
uint8_t gpio_af_timer = 0;
|
|
||||||
if(this->timer == TIM4) {
|
|
||||||
clk_ahb_timer = RCC_APB1Periph_TIM4;
|
|
||||||
gpio_af_timer = GPIO_AF_TIM4;
|
|
||||||
}
|
|
||||||
RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE);
|
|
||||||
if(this->port == GPIOD) {
|
|
||||||
clk_ahb_gpio = RCC_AHB1Periph_GPIOD;
|
|
||||||
}
|
|
||||||
RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE);
|
|
||||||
GPIO_Init(this->port, (GPIO_InitTypeDef *)this->port_cfg);
|
|
||||||
GPIO_PinAFConfig(this->port, this->pin_src, gpio_af_timer);
|
|
||||||
|
|
||||||
TIM_TimeBaseInit(this->timer, (TIM_TimeBaseInitTypeDef *)this->timer_cfg);
|
|
||||||
|
|
||||||
switch(this->channel) {
|
|
||||||
case channel_1:
|
|
||||||
TIM_OC1Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
|
|
||||||
TIM_OC1PreloadConfig(this->timer, TIM_OCPreload_Enable);
|
|
||||||
stm32f4_pwm_object.channel_1_max_period = this->timer_cfg->TIM_Period + 1;
|
|
||||||
break;
|
|
||||||
case channel_2:
|
|
||||||
TIM_OC2Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
|
|
||||||
TIM_OC2PreloadConfig(this->timer, TIM_OCPreload_Enable);
|
|
||||||
stm32f4_pwm_object.channel_2_max_period = this->timer_cfg->TIM_Period + 1;
|
|
||||||
break;
|
|
||||||
case channel_3:
|
|
||||||
TIM_OC3Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
|
|
||||||
TIM_OC3PreloadConfig(this->timer, TIM_OCPreload_Enable);
|
|
||||||
stm32f4_pwm_object.channel_3_max_period = this->timer_cfg->TIM_Period + 1;
|
|
||||||
break;
|
|
||||||
case channel_4:
|
|
||||||
TIM_OC4Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
|
|
||||||
TIM_OC4PreloadConfig(this->timer, TIM_OCPreload_Enable);
|
|
||||||
stm32f4_pwm_object.channel_4_max_period = this->timer_cfg->TIM_Period + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
TIM_ARRPreloadConfig(this->timer, ENABLE);
|
|
||||||
TIM_Cmd(this->timer, ENABLE);
|
|
||||||
stm32f4_pwm_object.used_channels++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stm32f4_pwm_close(const void *pwm)
|
|
||||||
{
|
|
||||||
if(NULL == pwm)
|
|
||||||
return -1;
|
|
||||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
|
||||||
stm32f4_pwm_set_duty_cycle(pwm, 0);
|
|
||||||
stm32f4_pwm_object.used_channels--;
|
|
||||||
if(stm32f4_pwm_object.used_channels == 0) {
|
|
||||||
TIM_Cmd(this->timer, DISABLE);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent)
|
|
||||||
{
|
|
||||||
if(NULL == pwm)
|
|
||||||
return -1;
|
|
||||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
|
||||||
switch(this->channel) {
|
|
||||||
case channel_1:
|
|
||||||
TIM_SetCompare1(this->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100);
|
|
||||||
break;
|
|
||||||
case channel_2:
|
|
||||||
TIM_SetCompare2(this->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100);
|
|
||||||
break;
|
|
||||||
case channel_3:
|
|
||||||
TIM_SetCompare3(this->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100);
|
|
||||||
break;
|
|
||||||
case channel_4:
|
|
||||||
TIM_SetCompare4(this->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
83
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
83
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* stm32f4_pwm.c
|
||||||
|
*
|
||||||
|
* Created on: Aug 9, 2016
|
||||||
|
* Author: tkl
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "stm32f4_gpio.h"
|
||||||
|
|
||||||
|
#include "pwm.h"
|
||||||
|
#include "stm32f4_pwm.h"
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
struct stm32f4_pwm_object {
|
||||||
|
uint8_t used_channels;
|
||||||
|
uint32_t channel_1_max_period;
|
||||||
|
uint32_t channel_2_max_period;
|
||||||
|
uint32_t channel_3_max_period;
|
||||||
|
uint32_t channel_4_max_period;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
int stm32f4_pwm_open(const void *pwm)
|
||||||
|
{
|
||||||
|
if(NULL == pwm)
|
||||||
|
return -1;
|
||||||
|
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||||
|
stm32f4_gpio_open(this->pwm_gpio);
|
||||||
|
if(this->timer_handle->Instance == TIM4) {
|
||||||
|
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||||
|
}
|
||||||
|
HAL_TIM_PWM_Init(this->timer_handle);
|
||||||
|
HAL_TIM_PWM_ConfigChannel(this->timer_handle, this->output_compare_cfg, this->channel);
|
||||||
|
|
||||||
|
TIM_MasterConfigTypeDef sMasterConfig;
|
||||||
|
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||||
|
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||||
|
HAL_TIMEx_MasterConfigSynchronization(this->timer_handle, &sMasterConfig);
|
||||||
|
|
||||||
|
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
|
||||||
|
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
|
||||||
|
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
|
||||||
|
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
|
||||||
|
sBreakDeadTimeConfig.DeadTime = 0;
|
||||||
|
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
|
||||||
|
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
|
||||||
|
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
|
||||||
|
HAL_TIMEx_ConfigBreakDeadTime(this->timer_handle, &sBreakDeadTimeConfig);
|
||||||
|
|
||||||
|
|
||||||
|
HAL_TIM_Base_Start(this->timer_handle);
|
||||||
|
HAL_TIM_PWM_Start(this->timer_handle, this->channel);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stm32f4_pwm_close(const void *pwm)
|
||||||
|
{
|
||||||
|
if(NULL == pwm)
|
||||||
|
return -1;
|
||||||
|
stm32f4_pwm_set_duty_cycle(pwm, 0);
|
||||||
|
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||||
|
HAL_TIM_Base_Stop(this->timer_handle);
|
||||||
|
HAL_TIM_PWM_Stop(this->timer_handle, this->channel);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent)
|
||||||
|
{
|
||||||
|
if(NULL == pwm)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||||
|
__HAL_TIM_SET_COMPARE(this->timer_handle, this->channel, this->timer_handle->Init.Period * duty_cycle_percent / 100);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -2963,7 +2963,7 @@ HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitT
|
|||||||
{
|
{
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
assert_param(IS_TIM_CHANNELS(Channel));
|
assert_param(IS_TIM_CHANNELS(Channel));
|
||||||
assert_param(IS_TIM_OC_MODE(sConfig->OCMode));
|
assert_param(IS_TIM_OC_MODE(sConfig->OCMode) || IS_TIM_PWM_MODE(sConfig->OCMode));
|
||||||
assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
|
assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
|
||||||
|
|
||||||
/* Check input state */
|
/* Check input state */
|
||||||
|
53
source/test/pwm/main.c
Normal file
53
source/test/pwm/main.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
*
|
||||||
|
* Created on: Aug 2, 2016
|
||||||
|
* Author: tkl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "driver.h"
|
||||||
|
#include "board.h"
|
||||||
|
#include "stack.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
#include "driver.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "shell.h"
|
||||||
|
|
||||||
|
#define TH_STACK_SIZE 256
|
||||||
|
stack_t th_stack[TH_STACK_SIZE];
|
||||||
|
struct thread_context th_ctx;
|
||||||
|
static void th_func(void *arg)
|
||||||
|
{
|
||||||
|
drv_open(&pwm_1);
|
||||||
|
drv_open(&pwm_2);
|
||||||
|
drv_open(&pwm_3);
|
||||||
|
drv_open(&pwm_4);
|
||||||
|
while(1) {
|
||||||
|
for(unsigned int duty = 0; duty < 100; duty++) {
|
||||||
|
drv_ioctl(&pwm_1, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
drv_ioctl(&pwm_2, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
drv_ioctl(&pwm_3, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
drv_ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
sleep_ms(10);
|
||||||
|
}
|
||||||
|
for(unsigned int duty = 98; duty > 0; duty--) {
|
||||||
|
drv_ioctl(&pwm_1, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
drv_ioctl(&pwm_2, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
drv_ioctl(&pwm_3, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
drv_ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
sleep_ms(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
board_init();
|
||||||
|
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW);
|
||||||
|
schedule_start();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
source/test/pwm/pwm.mk
Normal file
1
source/test/pwm/pwm.mk
Normal file
@ -0,0 +1 @@
|
|||||||
|
SRC_DIR += source/test/pwm
|
Loading…
Reference in New Issue
Block a user