cpu/stm32x: unified PWM driver
parent
6ab089e63e
commit
4d09d09ee4
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2016 Freie Universität Berlin
|
||||
* 2015 Engineering-Spirit
|
||||
* 2016 OTA keys S.A.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_stm32_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level PWM driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Fabian Nack <nack@inf.fu-berlin.de>
|
||||
* @author Nick v. IJzendoorn <nijzendoorn@engineering-spirit.nl>
|
||||
* @author Aurelien Gonce <aurelien.gonce@altran.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "assert.h"
|
||||
#include "periph/pwm.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#ifdef PWM_NUMOF
|
||||
|
||||
#define CCMR_LEFT (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | \
|
||||
TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2)
|
||||
#define CCMR_RIGHT (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | \
|
||||
TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2M_0 | \
|
||||
TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
|
||||
|
||||
static inline TIM_TypeDef *dev(pwm_t pwm)
|
||||
{
|
||||
return pwm_config[pwm].dev;
|
||||
}
|
||||
|
||||
uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
{
|
||||
uint32_t bus_clk = periph_apb_clk(pwm_config[pwm].bus);
|
||||
|
||||
/* verify parameters */
|
||||
assert((pwm < PWM_NUMOF) && ((freq * res) < bus_clk));
|
||||
|
||||
/* power on the used timer */
|
||||
pwm_poweron(pwm);
|
||||
/* reset configuration and CC channels */
|
||||
dev(pwm)->CR1 = 0;
|
||||
dev(pwm)->CR2 = 0;
|
||||
for (int i = 0; i < TIMER_CHAN; i++) {
|
||||
dev(pwm)->CCR[i] = 0;
|
||||
}
|
||||
|
||||
/* configure the used pins */
|
||||
for (unsigned i = 0; i < pwm_config[pwm].chan; i++) {
|
||||
gpio_init(pwm_config[pwm].pins[i], GPIO_OUT);
|
||||
gpio_init_af(pwm_config[pwm].pins[i], pwm_config[pwm].af);
|
||||
}
|
||||
|
||||
/* configure the PWM frequency and resolution by setting the auto-reload
|
||||
* and prescaler registers */
|
||||
dev(pwm)->PSC = (bus_clk / (res * freq)) - 1;
|
||||
dev(pwm)->ARR = res - 1;
|
||||
|
||||
/* set PWM mode */
|
||||
switch (mode) {
|
||||
case PWM_LEFT:
|
||||
dev(pwm)->CCMR1 = CCMR_LEFT;
|
||||
dev(pwm)->CCMR2 = CCMR_LEFT;
|
||||
break;
|
||||
case PWM_RIGHT:
|
||||
dev(pwm)->CCMR1 = CCMR_RIGHT;
|
||||
dev(pwm)->CCMR2 = CCMR_RIGHT;
|
||||
break;
|
||||
case PWM_CENTER:
|
||||
dev(pwm)->CCMR1 = 0;
|
||||
dev(pwm)->CCMR2 = 0;
|
||||
dev(pwm)->CR1 |= (TIM_CR1_CMS_0 | TIM_CR1_CMS_1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* enable PWM outputs and start PWM generation */
|
||||
#ifdef TIM_BDTR_MOE
|
||||
dev(pwm)->BDTR = TIM_BDTR_MOE;
|
||||
#endif
|
||||
dev(pwm)->CCER = (TIM_CCER_CC1E | TIM_CCER_CC2E |
|
||||
TIM_CCER_CC3E | TIM_CCER_CC4E);
|
||||
dev(pwm)->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
/* return the actual used PWM frequency */
|
||||
return (bus_clk / (res * (dev(pwm)->PSC + 1)));
|
||||
}
|
||||
|
||||
uint8_t pwm_channels(pwm_t pwm)
|
||||
{
|
||||
assert(pwm < PWM_NUMOF);
|
||||
return pwm_config[pwm].chan;
|
||||
}
|
||||
|
||||
void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value)
|
||||
{
|
||||
assert((pwm < PWM_NUMOF) && (channel < pwm_config[pwm].chan));
|
||||
|
||||
/* norm value to maximum possible value */
|
||||
if (value > dev(pwm)->ARR) {
|
||||
value = (uint16_t)dev(pwm)->ARR;
|
||||
}
|
||||
/* set new value */
|
||||
dev(pwm)->CCR[channel] = value;
|
||||
}
|
||||
|
||||
void pwm_start(pwm_t pwm)
|
||||
{
|
||||
assert(pwm < PWM_NUMOF);
|
||||
dev(pwm)->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void pwm_stop(pwm_t pwm)
|
||||
{
|
||||
assert(pwm < PWM_NUMOF);
|
||||
dev(pwm)->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void pwm_poweron(pwm_t pwm)
|
||||
{
|
||||
assert(pwm < PWM_NUMOF);
|
||||
periph_clk_en(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask);
|
||||
}
|
||||
|
||||
void pwm_poweroff(pwm_t pwm)
|
||||
{
|
||||
assert(pwm < PWM_NUMOF);
|
||||
periph_clk_dis(pwm_config[pwm].bus, pwm_config[pwm].rcc_mask);
|
||||
}
|
||||
|
||||
#endif /* PWM_NUMOF */
|
@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_stm32f3
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level PWM driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
/* guard file in case no PWM device is defined */
|
||||
#if (PWM_0_EN || PWM_1_EN)
|
||||
|
||||
/* pull the PWM header inside the guards for now. Guards will be removed on
|
||||
* adapting this driver implementation... */
|
||||
#include "periph/pwm.h"
|
||||
|
||||
uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
{
|
||||
TIM_TypeDef *tim = NULL;
|
||||
GPIO_TypeDef *port = NULL;
|
||||
uint32_t pins[PWM_MAX_CHANNELS];
|
||||
uint32_t af;
|
||||
int channels;
|
||||
uint32_t pwm_clk;
|
||||
|
||||
pwm_poweron(dev);
|
||||
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
tim = PWM_0_DEV;
|
||||
port = PWM_0_PORT;
|
||||
pins[0] = PWM_0_PIN_CH0;
|
||||
pins[1] = PWM_0_PIN_CH1;
|
||||
pins[2] = PWM_0_PIN_CH2;
|
||||
pins[3] = PWM_0_PIN_CH3;
|
||||
af = PWM_0_PIN_AF;
|
||||
channels = PWM_0_CHANNELS;
|
||||
pwm_clk = PWM_0_CLK;
|
||||
PWM_0_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
tim = PWM_1_DEV;
|
||||
port = PWM_1_PORT;
|
||||
pins[0] = PWM_1_PIN_CH0;
|
||||
pins[1] = PWM_1_PIN_CH1;
|
||||
pins[2] = PWM_1_PIN_CH2;
|
||||
pins[3] = PWM_1_PIN_CH3;
|
||||
af = PWM_1_PIN_AF;
|
||||
channels = PWM_1_CHANNELS;
|
||||
pwm_clk = PWM_1_CLK;
|
||||
PWM_1_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
pwm_poweroff(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setup pins: alternate function */
|
||||
for (int i = 0; i < channels; i++) {
|
||||
port->MODER &= ~(3 << (pins[i] * 2));
|
||||
port->MODER |= (2 << (pins[i] * 2));
|
||||
if (pins[i] < 8) {
|
||||
port->AFR[0] &= ~(0xf << (pins[i] * 4));
|
||||
port->AFR[0] |= (af << (pins[i] * 4));
|
||||
}
|
||||
else {
|
||||
port->AFR[1] &= ~(0xf << ((pins[i] - 8) * 4));
|
||||
port->AFR[1] |= (af << ((pins[i] - 8) * 4));
|
||||
}
|
||||
}
|
||||
|
||||
/* reset timer configuration registers */
|
||||
tim->CR1 = 0;
|
||||
tim->CR2 = 0;
|
||||
tim->CCMR1 = 0;
|
||||
tim->CCMR2 = 0;
|
||||
|
||||
/* set prescale and auto-reload registers to matching values for resolution and frequency */
|
||||
if ((res > 0xffff) || ((res * freq) > pwm_clk)) {
|
||||
return 0;
|
||||
}
|
||||
tim->PSC = (pwm_clk / (res * freq)) - 1;
|
||||
tim->ARR = res - 1;
|
||||
freq = (pwm_clk / (res * (tim->PSC + 1)));
|
||||
|
||||
/* set PWM mode */
|
||||
switch (mode) {
|
||||
case PWM_LEFT:
|
||||
tim->CCMR1 |= (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
|
||||
TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
|
||||
tim->CCMR2 |= (TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
|
||||
TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2);
|
||||
break;
|
||||
case PWM_RIGHT:
|
||||
tim->CCMR1 |= (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
|
||||
TIM_CCMR1_OC2M_0 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
|
||||
tim->CCMR2 |= (TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
|
||||
TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2);
|
||||
break;
|
||||
case PWM_CENTER:
|
||||
tim->CR1 |= (TIM_CR1_CMS_0 | TIM_CR1_CMS_1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* enable output on PWM pins */
|
||||
tim->CCER |= (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E);
|
||||
|
||||
/* enable PWM generation */
|
||||
pwm_start(dev);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
uint8_t pwm_channels(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
return PWM_0_CHANNELS;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
return PWM_1_CHANNELS;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_set(pwm_t dev, uint8_t channel, uint16_t value)
|
||||
{
|
||||
TIM_TypeDef *tim = NULL;
|
||||
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
tim = PWM_0_DEV;
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
tim = PWM_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
tim->CCR[channel] = value;
|
||||
}
|
||||
|
||||
void pwm_start(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_DEV->CR1 |= TIM_CR1_CEN;
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_DEV->CR1 |= TIM_CR1_CEN;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_stop(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_DEV->CR1 &= ~(TIM_CR1_CEN);
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_DEV->CR1 &= ~(TIM_CR1_CEN);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_poweron(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_poweroff(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* (PWM_0_EN || PWM_1_EN) */
|
@ -1,281 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_stm32f4
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level PWM driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Fabian Nack <nack@inf.fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
/* guard file in case no PWM device is defined */
|
||||
#if (PWM_0_EN || PWM_1_EN)
|
||||
|
||||
/* pull the PWM header inside the guards for now. Guards will be removed on
|
||||
* adapting this driver implementation... */
|
||||
#include "periph/pwm.h"
|
||||
|
||||
uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
{
|
||||
TIM_TypeDef *tim = NULL;
|
||||
GPIO_TypeDef *port = NULL;
|
||||
uint32_t pins[PWM_MAX_CHANNELS];
|
||||
uint32_t af = 0;
|
||||
uint32_t pwm_clk = 0;
|
||||
int channels = 0;
|
||||
|
||||
pwm_poweron(dev);
|
||||
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
tim = PWM_0_DEV;
|
||||
port = PWM_0_PORT;
|
||||
pins[0] = PWM_0_PIN_CH0;
|
||||
#if (PWM_0_CHANNELS > 1)
|
||||
pins[1] = PWM_0_PIN_CH1;
|
||||
#endif
|
||||
#if (PWM_0_CHANNELS > 2)
|
||||
pins[2] = PWM_0_PIN_CH2;
|
||||
#endif
|
||||
#if (PWM_0_CHANNELS > 3)
|
||||
pins[3] = PWM_0_PIN_CH3;
|
||||
#endif
|
||||
af = PWM_0_PIN_AF;
|
||||
channels = PWM_0_CHANNELS;
|
||||
pwm_clk = PWM_0_CLK;
|
||||
PWM_0_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
tim = PWM_1_DEV;
|
||||
port = PWM_1_PORT;
|
||||
pins[0] = PWM_1_PIN_CH0;
|
||||
#if (PWM_1_CHANNELS > 1)
|
||||
pins[1] = PWM_1_PIN_CH1;
|
||||
#endif
|
||||
#if (PWM_1_CHANNELS > 2)
|
||||
pins[2] = PWM_1_PIN_CH2;
|
||||
#endif
|
||||
#if (PWM_1_CHANNELS > 3)
|
||||
pins[3] = PWM_1_PIN_CH3;
|
||||
#endif
|
||||
af = PWM_1_PIN_AF;
|
||||
channels = PWM_1_CHANNELS;
|
||||
pwm_clk = PWM_1_CLK;
|
||||
PWM_1_PORT_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* setup pins: alternate function */
|
||||
for (int i = 0; i < channels; i++) {
|
||||
port->MODER &= ~(3 << (pins[i] * 2));
|
||||
port->MODER |= (2 << (pins[i] * 2));
|
||||
if (pins[i] < 8) {
|
||||
port->AFR[0] &= ~(0xf << (pins[i] * 4));
|
||||
port->AFR[0] |= (af << (pins[i] * 4));
|
||||
} else {
|
||||
port->AFR[1] &= ~(0xf << ((pins[i] - 8) * 4));
|
||||
port->AFR[1] |= (af << ((pins[i] - 8) * 4));
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset C/C and timer configuration register */
|
||||
switch (channels) {
|
||||
case 4:
|
||||
tim->CCR[3] = 0;
|
||||
/* Fall through */
|
||||
case 3:
|
||||
tim->CCR[2] = 0;
|
||||
tim->CR2 = 0;
|
||||
/* Fall through */
|
||||
case 2:
|
||||
tim->CCR[1] = 0;
|
||||
/* Fall through */
|
||||
case 1:
|
||||
tim->CCR[0] = 0;
|
||||
tim->CR1 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set prescale and auto-reload registers to matching values for resolution
|
||||
* and frequency */
|
||||
if (res > 0xffff || (res * freq) > pwm_clk) {
|
||||
return 0;
|
||||
}
|
||||
tim->PSC = (pwm_clk / (res * freq)) - 1;
|
||||
tim->ARR = res - 1;
|
||||
|
||||
/* calculate the actual PWM frequency */
|
||||
freq = (pwm_clk / (res * (tim->PSC + 1)));
|
||||
|
||||
/* set PWM mode */
|
||||
switch (mode) {
|
||||
case PWM_LEFT:
|
||||
tim->CCMR1 = (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
|
||||
TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
|
||||
if (channels > 2) {
|
||||
tim->CCMR2 = (TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
|
||||
TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2);
|
||||
}
|
||||
break;
|
||||
case PWM_RIGHT:
|
||||
tim->CCMR1 = (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
|
||||
TIM_CCMR1_OC2M_0 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2);
|
||||
if (channels > 2) {
|
||||
tim->CCMR2 = (TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 |
|
||||
TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2);
|
||||
}
|
||||
break;
|
||||
case PWM_CENTER:
|
||||
tim->CCMR1 = 0;
|
||||
if (channels > 2) {
|
||||
tim->CCMR2 = 0;
|
||||
}
|
||||
tim->CR1 |= (TIM_CR1_CMS_0 | TIM_CR1_CMS_1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* enable output on PWM pins */
|
||||
tim->CCER = (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E);
|
||||
|
||||
/* enable PWM outputs */
|
||||
tim->BDTR = TIM_BDTR_MOE;
|
||||
|
||||
/* enable timer ergo the PWM generation */
|
||||
pwm_start(dev);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
uint8_t pwm_channels(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
return PWM_0_CHANNELS;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
return PWM_1_CHANNELS;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_set(pwm_t dev, uint8_t channel, uint16_t value)
|
||||
{
|
||||
TIM_TypeDef *tim = NULL;
|
||||
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
tim = PWM_0_DEV;
|
||||
if (channel >= PWM_0_CHANNELS) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
tim = PWM_1_DEV;
|
||||
if (channel >= PWM_1_CHANNELS) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* norm value to maximum possible value */
|
||||
if (value > tim->ARR) {
|
||||
value = (uint32_t)tim->ARR;
|
||||
}
|
||||
|
||||
tim->CCR[channel] = value;
|
||||
}
|
||||
|
||||
void pwm_start(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_DEV->CR1 |= TIM_CR1_CEN;
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_DEV->CR1 |= TIM_CR1_CEN;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_stop(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_DEV->CR1 &= ~(TIM_CR1_CEN);
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_DEV->CR1 &= ~(TIM_CR1_CEN);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_poweron(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_poweroff(pwm_t dev)
|
||||
{
|
||||
switch (dev) {
|
||||
#if PWM_0_EN
|
||||
case PWM_0:
|
||||
PWM_0_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
#if PWM_1_EN
|
||||
case PWM_1:
|
||||
PWM_1_CLKDIS();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* (PWM_0_EN || PWM_1_EN) */
|
Loading…
Reference in New Issue