Merge branch 'feature/drv_pwm' into 'develop'
Feature/drv pwm See merge request !6
This commit is contained in:
commit
4d556a6235
23
.cproject
23
.cproject
@ -136,6 +136,7 @@
|
|||||||
<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>
|
||||||
@ -143,6 +144,7 @@
|
|||||||
</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>
|
||||||
@ -150,7 +152,6 @@
|
|||||||
</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>
|
||||||
@ -206,6 +207,7 @@
|
|||||||
</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>
|
||||||
@ -237,6 +239,7 @@
|
|||||||
</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>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
@ -282,6 +285,22 @@
|
|||||||
<useDefaultCommand>false</useDefaultCommand>
|
<useDefaultCommand>false</useDefaultCommand>
|
||||||
<runAllBuilders>true</runAllBuilders>
|
<runAllBuilders>true</runAllBuilders>
|
||||||
</target>
|
</target>
|
||||||
|
<target name="test pwm" 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="test pwm install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||||
|
<buildCommand>make</buildCommand>
|
||||||
|
<buildArguments>TEST_APP=pwm BOARD=stm32f4-discovery DEBUG=y</buildArguments>
|
||||||
|
<buildTarget>install</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>
|
||||||
@ -308,6 +327,7 @@
|
|||||||
</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>
|
||||||
@ -315,6 +335,7 @@
|
|||||||
</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>
|
||||||
|
2
Makefile
2
Makefile
@ -83,7 +83,7 @@ doc:
|
|||||||
@$(MKDIR) $(DOC_DIR)
|
@$(MKDIR) $(DOC_DIR)
|
||||||
(cat $(DOXYFILE) ; echo "INPUT=$(DOC_SRC)" ; echo "OUTPUT_DIRECTORY=$(DOC_DIR)") | doxygen -
|
(cat $(DOXYFILE) ; echo "INPUT=$(DOC_SRC)" ; echo "OUTPUT_DIRECTORY=$(DOC_DIR)") | doxygen -
|
||||||
|
|
||||||
test: check $(OBJECTS) $(ASM_OBJECTS)
|
test: $(OBJECTS) $(ASM_OBJECTS)
|
||||||
@$(MKDIR) $(EXE_DIR)
|
@$(MKDIR) $(EXE_DIR)
|
||||||
@$(MKDIR) $(MAP_DIR)
|
@$(MKDIR) $(MAP_DIR)
|
||||||
@$(MKDIR) $(SIZE_DIR)
|
@$(MKDIR) $(SIZE_DIR)
|
||||||
|
@ -9,8 +9,8 @@ endif
|
|||||||
CROSS_COMPILE=arm-none-eabi-
|
CROSS_COMPILE=arm-none-eabi-
|
||||||
|
|
||||||
INCLUDES += \
|
INCLUDES += \
|
||||||
/usr/lib/arm-none-eabi/include \
|
/opt/arm-2011.09/arm-none-eabi/include \
|
||||||
/usr/lib/gcc/arm-none-eabi/4.8/include
|
/opt/arm-2011.09/lib/gcc/arm-none-eabi/4.6.1/include
|
||||||
|
|
||||||
ifeq ($(DEBUG),y)
|
ifeq ($(DEBUG),y)
|
||||||
OPTIM = 0
|
OPTIM = 0
|
||||||
@ -35,7 +35,6 @@ CFLAGS += \
|
|||||||
-mfloat-abi=softfp \
|
-mfloat-abi=softfp \
|
||||||
-fdata-sections \
|
-fdata-sections \
|
||||||
-ffunction-sections
|
-ffunction-sections
|
||||||
# -D inline= -mthumb\
|
|
||||||
|
|
||||||
CPPCHECK_FLAGS += \
|
CPPCHECK_FLAGS += \
|
||||||
-D USE_STDPERIPH_DRIVER\
|
-D USE_STDPERIPH_DRIVER\
|
||||||
|
@ -13,15 +13,18 @@
|
|||||||
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
#include "pwm.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
#include "sys_tick.h"
|
#include "sys_tick.h"
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
#include "stm32f4_gpio.h"
|
#include "stm32f4_gpio.h"
|
||||||
|
#include "stm32f4_pwm.h"
|
||||||
#include "stm32f4_uart.h"
|
#include "stm32f4_uart.h"
|
||||||
#include "stm32_sys_tick.h"
|
#include "stm32_sys_tick.h"
|
||||||
|
|
||||||
|
|
||||||
// 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 =
|
||||||
STM32_SYS_TICK_TIME_BASE_MS;
|
STM32_SYS_TICK_TIME_BASE_MS;
|
||||||
@ -36,6 +39,62 @@ static const struct loki_timer timer_1 = {
|
|||||||
&timer_fp
|
&timer_fp
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PWM CHANNEL 4
|
||||||
|
/* apb1 clock = 84MHz */
|
||||||
|
/* period_reg = src_clk / presc / cnt_clk */
|
||||||
|
/* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */
|
||||||
|
static const TIM_TimeBaseInitTypeDef timer_4_cfg = {
|
||||||
|
.TIM_RepetitionCounter = 0x0000,
|
||||||
|
.TIM_Prescaler = 0,
|
||||||
|
.TIM_ClockDivision = TIM_CKD_DIV1,
|
||||||
|
.TIM_CounterMode = TIM_CounterMode_Up,
|
||||||
|
.TIM_Period = 4199
|
||||||
|
};
|
||||||
|
|
||||||
|
static const TIM_OCInitTypeDef t4_output_compare_cfg = {
|
||||||
|
.TIM_OutputNState = TIM_OutputNState_Disable,
|
||||||
|
.TIM_OCNPolarity = TIM_OCPolarity_High,
|
||||||
|
.TIM_OCIdleState = TIM_OCIdleState_Reset,
|
||||||
|
.TIM_OCNIdleState = TIM_OCNIdleState_Set,
|
||||||
|
.TIM_OCMode = TIM_OCMode_PWM1,
|
||||||
|
.TIM_OCPolarity = TIM_OCPolarity_High,
|
||||||
|
.TIM_OutputState = TIM_OutputState_Enable,
|
||||||
|
.TIM_Pulse = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GPIO_InitTypeDef port_cfg = {
|
||||||
|
.GPIO_Pin = GPIO_Pin_15,
|
||||||
|
.GPIO_Mode = GPIO_Mode_AF,
|
||||||
|
.GPIO_OType = GPIO_OType_PP,
|
||||||
|
.GPIO_PuPd = GPIO_PuPd_UP,
|
||||||
|
.GPIO_Speed = GPIO_Speed_100MHz,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct stm32f4_pwm str32f4_pwm = {
|
||||||
|
.timer = TIM4,
|
||||||
|
.timer_cfg = &timer_4_cfg,
|
||||||
|
.output_compare_cfg = &t4_output_compare_cfg,
|
||||||
|
.port = GPIOD,
|
||||||
|
.pin_src = GPIO_PinSource15,
|
||||||
|
.port_cfg = &port_cfg,
|
||||||
|
.channel = channel_4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pwm pwm_ch4 = {
|
||||||
|
.arch_dep_device = &str32f4_pwm,
|
||||||
|
.fp = &stm32f4_pwm_fp,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef TEST_APP
|
||||||
|
static const struct driver pwm_4 = {
|
||||||
|
#else
|
||||||
|
const struct driver pwm_4 = {
|
||||||
|
#endif
|
||||||
|
DRIVER_TYPE_PWM,
|
||||||
|
&pwm_ch4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// UART 1
|
||||||
static char console_linear_buffer[80];
|
static char console_linear_buffer[80];
|
||||||
static struct ringbuffer console_buffer = {
|
static struct ringbuffer console_buffer = {
|
||||||
console_linear_buffer,
|
console_linear_buffer,
|
||||||
|
40
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
40
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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_
|
||||||
|
|
||||||
|
enum stm32f4_pwm_channel {
|
||||||
|
channel_1 = 1,
|
||||||
|
channel_2,
|
||||||
|
channel_3,
|
||||||
|
channel_4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stm32f4_pwm {
|
||||||
|
TIM_TypeDef *timer;
|
||||||
|
const TIM_TimeBaseInitTypeDef *timer_cfg;
|
||||||
|
const TIM_OCInitTypeDef *output_compare_cfg;
|
||||||
|
const TIM_BDTRInitTypeDef *bdtr_cfg;
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint8_t pin_src;
|
||||||
|
const GPIO_InitTypeDef *port_cfg;
|
||||||
|
enum stm32f4_pwm_channel channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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_ */
|
113
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
113
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
@ -11,6 +11,7 @@
|
|||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#include "pwm.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
@ -30,6 +31,9 @@ int open(const struct driver *driver)
|
|||||||
case DRIVER_TYPE_I2C:
|
case DRIVER_TYPE_I2C:
|
||||||
ret = i2c_open((struct i2c *)(driver->device_driver));
|
ret = i2c_open((struct i2c *)(driver->device_driver));
|
||||||
break;
|
break;
|
||||||
|
case DRIVER_TYPE_PWM:
|
||||||
|
ret = pwm_open((const struct pwm *)(driver->device_driver));
|
||||||
|
break;
|
||||||
case DRIVER_TYPE_RTC:
|
case DRIVER_TYPE_RTC:
|
||||||
ret = rtc_open((const struct rtc *)(driver->device_driver));
|
ret = rtc_open((const struct rtc *)(driver->device_driver));
|
||||||
break;
|
break;
|
||||||
@ -58,6 +62,9 @@ int close(const struct driver *driver)
|
|||||||
case DRIVER_TYPE_I2C:
|
case DRIVER_TYPE_I2C:
|
||||||
ret = i2c_close((struct i2c *)(driver->device_driver));
|
ret = i2c_close((struct i2c *)(driver->device_driver));
|
||||||
break;
|
break;
|
||||||
|
case DRIVER_TYPE_PWM:
|
||||||
|
ret = pwm_close((const struct pwm *)(driver->device_driver));
|
||||||
|
break;
|
||||||
case DRIVER_TYPE_RTC:
|
case DRIVER_TYPE_RTC:
|
||||||
ret = rtc_close((const struct rtc *)(driver->device_driver));
|
ret = rtc_close((const struct rtc *)(driver->device_driver));
|
||||||
break;
|
break;
|
||||||
@ -88,6 +95,9 @@ int read(const struct driver *driver, char *buffer, int len)
|
|||||||
break;
|
break;
|
||||||
case DRIVER_TYPE_I2C:
|
case DRIVER_TYPE_I2C:
|
||||||
break;
|
break;
|
||||||
|
case DRIVER_TYPE_PWM:
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
case DRIVER_TYPE_RTC:
|
case DRIVER_TYPE_RTC:
|
||||||
break;
|
break;
|
||||||
case DRIVER_TYPE_SPI:
|
case DRIVER_TYPE_SPI:
|
||||||
@ -118,6 +128,9 @@ int write(const struct driver *driver, const char *buffer, int len)
|
|||||||
break;
|
break;
|
||||||
case DRIVER_TYPE_I2C:
|
case DRIVER_TYPE_I2C:
|
||||||
break;
|
break;
|
||||||
|
case DRIVER_TYPE_PWM:
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
case DRIVER_TYPE_RTC:
|
case DRIVER_TYPE_RTC:
|
||||||
break;
|
break;
|
||||||
case DRIVER_TYPE_SPI:
|
case DRIVER_TYPE_SPI:
|
||||||
@ -128,3 +141,31 @@ int write(const struct driver *driver, const char *buffer, int len)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ioctl(const struct driver *driver, unsigned int cmd, const void *data)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
if(NULL == driver)
|
||||||
|
return ret;
|
||||||
|
switch(driver->driver_type) {
|
||||||
|
case DRIVER_TYPE_ADC:
|
||||||
|
break;
|
||||||
|
case DRIVER_TYPE_GPIO:
|
||||||
|
break;
|
||||||
|
case DRIVER_TYPE_I2C:
|
||||||
|
break;
|
||||||
|
case DRIVER_TYPE_PWM:
|
||||||
|
if(cmd == IOCTL_PWM_SET_DUTY_CYCLE) {
|
||||||
|
unsigned int *duty = (unsigned int *)data;
|
||||||
|
pwm_set_duty_cycle((const struct pwm *)(driver->device_driver), *duty);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DRIVER_TYPE_RTC:
|
||||||
|
break;
|
||||||
|
case DRIVER_TYPE_SPI:
|
||||||
|
break;
|
||||||
|
case DRIVER_TYPE_UART:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
35
source/firmware/kernel/driver/include/pwm.h
Normal file
35
source/firmware/kernel/driver/include/pwm.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* pwm.h
|
||||||
|
*
|
||||||
|
* Created on: Aug 9, 2016
|
||||||
|
* Author: tkl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_
|
||||||
|
#define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_
|
||||||
|
|
||||||
|
//! \brief Function pointer to the open function.
|
||||||
|
typedef int (*pwm_fp_open_t)(const void*);
|
||||||
|
|
||||||
|
//! \brief Function pointer to the close function.
|
||||||
|
typedef int (*pwm_fp_close_t)(const void*);
|
||||||
|
|
||||||
|
//! \brief Function pointer to the read function.
|
||||||
|
typedef int (*pwm_fp_set_duty_cycle_t)(const void*, unsigned int duty_cycle_percent);
|
||||||
|
|
||||||
|
struct pwm_fp {
|
||||||
|
const pwm_fp_open_t open;
|
||||||
|
const pwm_fp_close_t close;
|
||||||
|
const pwm_fp_set_duty_cycle_t set_duty_cycle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pwm {
|
||||||
|
const void *arch_dep_device; //!< Architecture depended pwm device (i.e. stm32f10x_pwm_t).
|
||||||
|
const struct pwm_fp *fp; //!< Function pointer for the pwm driver access.
|
||||||
|
};
|
||||||
|
|
||||||
|
int pwm_open(const struct pwm *device);
|
||||||
|
int pwm_close(const struct pwm *device);
|
||||||
|
int pwm_set_duty_cycle(const struct pwm *device, unsigned int duty_cycle_percent);
|
||||||
|
|
||||||
|
#endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_ */
|
33
source/firmware/kernel/driver/pwm.c
Normal file
33
source/firmware/kernel/driver/pwm.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* pwm.c
|
||||||
|
*
|
||||||
|
* Created on: Aug 9, 2016
|
||||||
|
* Author: tkl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <pwm.h>
|
||||||
|
|
||||||
|
int pwm_open(const struct pwm *device)
|
||||||
|
{
|
||||||
|
if(NULL == device)
|
||||||
|
return -1;
|
||||||
|
pwm_fp_open_t open = device->fp->open;
|
||||||
|
return open(device->arch_dep_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pwm_close(const struct pwm *device)
|
||||||
|
{
|
||||||
|
if(NULL == device)
|
||||||
|
return -1;
|
||||||
|
pwm_fp_close_t close = device->fp->close;
|
||||||
|
return close(device->arch_dep_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pwm_set_duty_cycle(const struct pwm *device, unsigned int duty_cycle_percent)
|
||||||
|
{
|
||||||
|
if(NULL == device)
|
||||||
|
return -1;
|
||||||
|
pwm_fp_set_duty_cycle_t set = device->fp->set_duty_cycle;
|
||||||
|
return set(device->arch_dep_device, duty_cycle_percent);
|
||||||
|
}
|
@ -8,10 +8,13 @@
|
|||||||
#ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_
|
#ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_
|
||||||
#define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_
|
#define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_
|
||||||
|
|
||||||
|
#define IOCTL_PWM_SET_DUTY_CYCLE 0
|
||||||
|
|
||||||
enum driver_type {
|
enum driver_type {
|
||||||
DRIVER_TYPE_ADC,
|
DRIVER_TYPE_ADC,
|
||||||
DRIVER_TYPE_GPIO,
|
DRIVER_TYPE_GPIO,
|
||||||
DRIVER_TYPE_I2C,
|
DRIVER_TYPE_I2C,
|
||||||
|
DRIVER_TYPE_PWM,
|
||||||
DRIVER_TYPE_RTC,
|
DRIVER_TYPE_RTC,
|
||||||
DRIVER_TYPE_SPI,
|
DRIVER_TYPE_SPI,
|
||||||
DRIVER_TYPE_UART
|
DRIVER_TYPE_UART
|
||||||
@ -26,5 +29,6 @@ int open(const struct driver *driver);
|
|||||||
int close(const struct driver *driver);
|
int close(const struct driver *driver);
|
||||||
int read(const struct driver *driver, char *buffer, int len);
|
int read(const struct driver *driver, char *buffer, int len);
|
||||||
int write(const struct driver *driver, const char *buffer, int len);
|
int write(const struct driver *driver, const char *buffer, int len);
|
||||||
|
int ioctl(const struct driver *driver, unsigned int cmd, const void *data);
|
||||||
|
|
||||||
#endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ */
|
#endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_DRIVER_H_ */
|
||||||
|
@ -23,9 +23,9 @@ struct shell_object {
|
|||||||
|
|
||||||
struct shell_object shell_object;
|
struct shell_object shell_object;
|
||||||
|
|
||||||
#define RX_STACK_SIZE 256
|
#define TH_STACK_SIZE 256
|
||||||
stack_t rx_stack[RX_STACK_SIZE];
|
stack_t th_stack[TH_STACK_SIZE];
|
||||||
struct thread_context rx_thread;
|
struct thread_context th_ctx;
|
||||||
|
|
||||||
static void parse(const char *buffer, unsigned int len)
|
static void parse(const char *buffer, unsigned int len)
|
||||||
{
|
{
|
||||||
@ -71,7 +71,7 @@ int shell_init(const struct driver *shell_device)
|
|||||||
return -1;
|
return -1;
|
||||||
list_init(&shell_object.command_list);
|
list_init(&shell_object.command_list);
|
||||||
shell_object.shell_device = shell_device;
|
shell_object.shell_device = shell_device;
|
||||||
thread_create(&rx_thread, rx_stack, RX_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW);
|
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, rx_func, NULL, THREAD_PRIO_LOW);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
source/test/pwm/main.c
Normal file
48
source/test/pwm/main.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
unsigned int duty = 0;
|
||||||
|
open(&pwm_4);
|
||||||
|
while(1) {
|
||||||
|
while(duty < 100) {
|
||||||
|
ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
pwm_set_duty_cycle(&pwm_ch4, duty);
|
||||||
|
sleep_ms(10);
|
||||||
|
duty++;
|
||||||
|
}
|
||||||
|
while(duty > 0) {
|
||||||
|
ioctl(&pwm_4, IOCTL_PWM_SET_DUTY_CYCLE, (const void *)&duty);
|
||||||
|
sleep_ms(10);
|
||||||
|
duty--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW);
|
||||||
|
schedule_start();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
4
source/test/pwm/pwm.mk
Normal file
4
source/test/pwm/pwm.mk
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CHECK_FOLDER += source/test/pwm
|
||||||
|
SUB_FOLDER += source/test/pwm
|
||||||
|
INCLUDES += source/test/pwm
|
||||||
|
DOC_SRC += source/test/pwm
|
@ -1,3 +1,6 @@
|
|||||||
ifeq ($(TEST_APP), shell)
|
ifeq ($(TEST_APP), shell)
|
||||||
include source/test/shell/shell.mk
|
include source/test/shell/shell.mk
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(TEST_APP), pwm)
|
||||||
|
include source/test/pwm/pwm.mk
|
||||||
|
endif
|
||||||
|
Loading…
Reference in New Issue
Block a user