Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timer driver refactoring #3120

Merged
merged 11 commits into from
May 23, 2018
1 change: 1 addition & 0 deletions make/mcu/STM32F3.mk
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ MCU_COMMON_SRC = \
drivers/dma.c \
drivers/serial_uart_stm32f30x.c \
drivers/system_stm32f30x.c \
drivers/timer_impl_stdperiph.c \
drivers/timer_stm32f30x.c

DSP_LIB := $(ROOT)/lib/main/CMSIS/DSP
Expand Down
2 changes: 2 additions & 0 deletions make/mcu/STM32F4.mk
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ MCU_COMMON_SRC = \
drivers/serial_softserial.c \
drivers/serial_uart_stm32f4xx.c \
drivers/system_stm32f4xx.c \
drivers/timer.c \
drivers/timer_impl_stdperiph.c \
drivers/timer_stm32f4xx.c \
drivers/dma_stm32f4xx.c

Expand Down
4 changes: 2 additions & 2 deletions make/mcu/STM32F7.mk
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ MCU_COMMON_SRC = \
drivers/dma_stm32f7xx.c \
drivers/inverter.c \
drivers/bus_spi_hal.c \
drivers/timer_hal.c \
drivers/timer.c \
drivers/timer_impl_hal.c \
drivers/timer_stm32f7xx.c \
drivers/system_stm32f7xx.c \
drivers/serial_uart_stm32f7xx.c \
Expand All @@ -158,7 +159,6 @@ MCU_COMMON_SRC = \
MCU_EXCLUDES = \
drivers/bus_spi.c \
drivers/bus_i2c.c \
drivers/timer.c \
drivers/serial_uart.c

DSP_LIB := $(ROOT)/lib/main/CMSIS/DSP
Expand Down
10 changes: 9 additions & 1 deletion src/main/common/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "platform.h"

#include "build/debug.h"
#include "drivers/resource.h"
#include "common/memory.h"
#include "fc/runtime_config.h"

Expand All @@ -37,8 +38,9 @@

static uint32_t dynHeap[DYNAMIC_HEAP_SIZE / sizeof(uint32_t)];
static uint32_t dynHeapFreeWord = 0;
static size_t dynHeapUsage[OWNER_TOTAL_COUNT];

void * memAllocate(size_t wantedSize)
void * memAllocate(size_t wantedSize, resourceOwner_e owner)
{
void * retPointer = NULL;
const size_t wantedWords = (wantedSize + sizeof(uint32_t) - 1) / sizeof(uint32_t);
Expand All @@ -47,6 +49,7 @@ void * memAllocate(size_t wantedSize)
// Success
retPointer = &dynHeap[dynHeapFreeWord];
dynHeapFreeWord += wantedWords;
dynHeapUsage[owner] += wantedWords * sizeof(uint32_t);
DEBUG_TRACE("Memory allocated. Free memory = %d", memGetAvailableBytes());
}
else {
Expand All @@ -58,6 +61,11 @@ void * memAllocate(size_t wantedSize)
return retPointer;
}

size_t memGetUsedBytesByOwner(resourceOwner_e owner)
{
return (owner == OWNER_FREE) ? memGetAvailableBytes() : dynHeapUsage[owner];
}

size_t memGetAvailableBytes(void)
{
return (DYNAMIC_HEAP_SIZE / sizeof(uint32_t) - dynHeapFreeWord) * sizeof(uint32_t);
Expand Down
4 changes: 3 additions & 1 deletion src/main/common/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#pragma once

#include <stdlib.h>
#include "drivers/resource.h"

size_t memGetAvailableBytes(void);
void * memAllocate(size_t wantedSize);
size_t memGetUsedBytesByOwner(resourceOwner_e owner);
void * memAllocate(size_t wantedSize, resourceOwner_e owner);
2 changes: 1 addition & 1 deletion src/main/drivers/light_ws2811strip_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void ws2811LedStripHardwareInit(void)

/* Compute the prescaler value */
uint16_t prescaler = timerGetPrescalerByDesiredMhz(timer, WS2811_TIMER_MHZ);
uint16_t period = timerGetPeriodByPrescaler(timer, prescaler, WS2811_CARRIER_HZ);
uint16_t period = 1000000 * WS2811_TIMER_MHZ / WS2811_CARRIER_HZ;

BIT_COMPARE_1 = period / 3 * 2;
BIT_COMPARE_0 = period / 3;
Expand Down
31 changes: 3 additions & 28 deletions src/main/drivers/light_ws2811strip_stdperiph.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)

void ws2811LedStripHardwareInit(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure;

const timerHardware_t *timerHardware = timerGetByTag(IO_TAG(WS2811_PIN), TIM_USE_ANY);
Expand All @@ -84,41 +82,18 @@ void ws2811LedStripHardwareInit(void)
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerHardware->alternateFunction);

RCC_ClockCmd(timerRCC(timer), ENABLE);

// Stop timer
TIM_Cmd(timer, DISABLE);

/* Compute the prescaler value */
uint16_t prescaler = timerGetPrescalerByDesiredMhz(timer, WS2811_TIMER_MHZ);
uint16_t period = timerGetPeriodByPrescaler(timer, prescaler, WS2811_CARRIER_HZ);
uint16_t period = 1000000 * WS2811_TIMER_MHZ / WS2811_CARRIER_HZ;

BIT_COMPARE_1 = period / 3 * 2;
BIT_COMPARE_0 = period / 3;

/* Time base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = period; // 800kHz
TIM_TimeBaseStructure.TIM_Prescaler = prescaler;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);

/* PWM1 Mode configuration */
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) {
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
} else {
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
}
TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 0;

timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
timerConfigBase(timer, period, WS2811_TIMER_MHZ);
timerPWMConfigChannel(timer, timerHardware->channel, timerHardware->output & TIMER_OUTPUT_N_CHANNEL, timerHardware->output & TIMER_OUTPUT_INVERTED, 0);

TIM_CtrlPWMOutputs(timer, ENABLE);
TIM_ARRPreloadConfig(timer, ENABLE);
Expand Down
2 changes: 1 addition & 1 deletion src/main/drivers/pwm_esc_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ uint8_t hardwareMotorType = MOTOR_UNKNOWN;

void detectBrushedESC(void)
{
for (int i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
for (int i = 0; i < timerHardwareCount; i++) {
if (timerHardware[i].usageFlags & TIM_USE_MC_MOTOR) {
IO_t MotorDetectPin = IOGetByTag(timerHardware[i].tag);
IOInit(MotorDetectPin, OWNER_SYSTEM, RESOURCE_INPUT, 0);
Expand Down
15 changes: 8 additions & 7 deletions src/main/drivers/pwm_mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@

#include "platform.h"

#include "common/memory.h"
#include "drivers/io.h"
#include "io_impl.h"
#include "timer.h"

#include "drivers/io_impl.h"
#include "drivers/timer.h"
#include "drivers/logging.h"

#include "pwm_output.h"
#include "pwm_mapping.h"
#include "rx_pwm.h"
#include "drivers/pwm_output.h"
#include "drivers/pwm_mapping.h"
#include "drivers/rx_pwm.h"

enum {
MAP_TO_NONE,
Expand Down Expand Up @@ -59,12 +59,13 @@ bool CheckGPIOPinSource(ioTag_t tag, GPIO_TypeDef *gpio, uint16_t pin)
pwmIOConfiguration_t *pwmInit(drv_pwm_config_t *init)
{
memset(&pwmIOConfiguration, 0, sizeof(pwmIOConfiguration));
pwmIOConfiguration.ioConfigurations = memAllocate(sizeof(pwmPortConfiguration_t) * timerHardwareCount, OWNER_PWMIO);

#if defined(USE_RX_PWM) || defined(USE_RX_PPM)
int channelIndex = 0;
#endif

for (int timerIndex = 0; timerIndex < USABLE_TIMER_CHANNEL_COUNT; timerIndex++) {
for (int timerIndex = 0; timerIndex < timerHardwareCount; timerIndex++) {
const timerHardware_t *timerHardwarePtr = &timerHardware[timerIndex];
int type = MAP_TO_NONE;

Expand Down
2 changes: 1 addition & 1 deletion src/main/drivers/pwm_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ typedef struct pwmIOConfiguration_s {
uint8_t ioCount;
uint8_t pwmInputCount;
uint8_t ppmInputCount;
pwmPortConfiguration_t ioConfigurations[USABLE_TIMER_CHANNEL_COUNT];
pwmPortConfiguration_t * ioConfigurations;
} pwmIOConfiguration_t;

// This indexes into the read-only hardware definition structure, timerHardware_t
Expand Down
79 changes: 5 additions & 74 deletions src/main/drivers/pwm_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,87 +62,18 @@ static uint8_t allocatedOutputPortCount = 0;

static bool pwmMotorsEnabled = true;


static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value, uint8_t output)
{
#if defined(USE_HAL_DRIVER)
TIM_HandleTypeDef* Handle = timerFindTimerHandle(tim);
if (Handle == NULL) return;

TIM_OC_InitTypeDef TIM_OCInitStructure;

TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1;
TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;
TIM_OCInitStructure.OCPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPOLARITY_LOW : TIM_OCPOLARITY_HIGH;
TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_SET;
TIM_OCInitStructure.OCNPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPOLARITY_LOW : TIM_OCNPOLARITY_HIGH;
TIM_OCInitStructure.Pulse = value;
TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;

HAL_TIM_PWM_ConfigChannel(Handle, &TIM_OCInitStructure, channel);
#else
TIM_OCInitTypeDef TIM_OCInitStructure;

TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
if (output & TIMER_OUTPUT_N_CHANNEL) {
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCNPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
} else {
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCPolarity = (output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
}
TIM_OCInitStructure.TIM_Pulse = value;

timerOCInit(tim, channel, &TIM_OCInitStructure);
timerOCPreloadConfig(tim, channel, TIM_OCPreload_Enable);
#endif
}

static void pwmOutConfigTimer(pwmOutputPort_t * p, const timerHardware_t *timerHardware, uint8_t mhz, uint16_t period, uint16_t value)
{
#if defined(USE_HAL_DRIVER)
TIM_HandleTypeDef* Handle = timerFindTimerHandle(timerHardware->tim);
if (Handle == NULL) return;
#endif
timerConfigBase(timerHardware->tim, period, mhz);
timerPWMConfigChannel(timerHardware->tim, timerHardware->channel, timerHardware->output & TIMER_OUTPUT_N_CHANNEL, timerHardware->output & TIMER_OUTPUT_INVERTED, value);

configTimeBase(timerHardware->tim, period, mhz);
pwmOCConfig(timerHardware->tim, timerHardware->channel, value, timerHardware->output);

#if defined(USE_HAL_DRIVER)
if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL)
HAL_TIMEx_PWMN_Start(Handle, timerHardware->channel);
else
HAL_TIM_PWM_Start(Handle, timerHardware->channel);
HAL_TIM_Base_Start(Handle);

switch (timerHardware->channel) {
case TIM_CHANNEL_1:
p->ccr = &timerHardware->tim->CCR1;
break;
case TIM_CHANNEL_2:
p->ccr = &timerHardware->tim->CCR2;
break;
case TIM_CHANNEL_3:
p->ccr = &timerHardware->tim->CCR3;
break;
case TIM_CHANNEL_4:
p->ccr = &timerHardware->tim->CCR4;
break;
}
#else
if (timerHardware->output & TIMER_OUTPUT_ENABLED) {
TIM_CtrlPWMOutputs(timerHardware->tim, ENABLE);
timerPWMStart(timerHardware->tim, timerHardware->channel, timerHardware->output & TIMER_OUTPUT_N_CHANNEL);
}
TIM_Cmd(timerHardware->tim, ENABLE);

p->ccr = timerCCR(timerHardware->tim, timerHardware->channel);
#endif
timerEnable(timerHardware->tim);

p->ccr = timerCCR(timerHardware->tim, timerHardware->channel);
p->period = period;
p->tim = timerHardware->tim;

Expand Down
2 changes: 1 addition & 1 deletion src/main/drivers/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "drivers/resource.h"

const char * const ownerNames[OWNER_TOTAL_COUNT] = {
"FREE", "PWM", "PPM", "MOTOR", "SERVO", "SOFTSERIAL", "ADC", "SERIAL", "DEBUG", "TIMER",
"FREE", "PWM/IO", "PWM", "PPM", "MOTOR", "SERVO", "SOFTSERIAL", "ADC", "SERIAL", "DEBUG", "TIMER",
"RANGEFINDER", "SYSTEM", "SPI", "I2C", "SDCARD", "FLASH", "USB", "BEEPER", "OSD",
"BARO", "MPU", "INVERTER", "LED STRIP", "LED", "RECEIVER", "TRANSMITTER",
"NRF24", "VTX", "SPI_PREINIT", "COMPASS", "AIRSPEED", "OLED DISPLAY",
Expand Down
1 change: 1 addition & 0 deletions src/main/drivers/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

typedef enum {
OWNER_FREE = 0,
OWNER_PWMIO,
OWNER_PWMINPUT,
OWNER_PPMINPUT,
OWNER_MOTOR,
Expand Down
Loading