Merged in slorquet/nuttx/32l4_pwm (pull request #146)

32l4 pwm
This commit is contained in:
Gregory Nutt 2016-10-14 16:55:03 +00:00
commit e3c553e58d
7 changed files with 523 additions and 11 deletions

View File

@ -731,6 +731,13 @@ config STM32L4_TIM1_CH1OUT
---help---
Enables channel 1 output.
config STM32L4_TIM1_CH1NOUT
bool "TIM1 Channel 1 Complementary Output"
default n
depends on STM32L4_TIM1_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_TIM1_CHANNEL1
config STM32L4_TIM1_CHANNEL2
@ -754,6 +761,13 @@ config STM32L4_TIM1_CH2OUT
---help---
Enables channel 2 output.
config STM32L4_TIM1_CH2NOUT
bool "TIM1 Channel 2 Complemenrary Output"
default n
depends on STM32L4_TIM1_CH2OUT
---help---
Enables channel 2 complementary output.
endif # STM32L4_TIM1_CHANNEL2
config STM32L4_TIM1_CHANNEL3
@ -777,6 +791,13 @@ config STM32L4_TIM1_CH3OUT
---help---
Enables channel 3 output.
config STM32L4_TIM1_CH3NOUT
bool "TIM1 Channel 3 Complementary Output"
default n
depends on STM32L4_TIM1_CH3OUT
---help---
Enables channel 3 complementary output.
endif # STM32L4_TIM1_CHANNEL3
config STM32L4_TIM1_CHANNEL4
@ -1426,6 +1447,13 @@ config STM32L4_TIM8_CH1OUT
---help---
Enables channel 1 output.
config STM32L4_TIM8_CH1NOUT
bool "TIM8 Channel 1 Complementary Output"
default n
depends on STM32L4_TIM8_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_TIM8_CHANNEL1
config STM32L4_TIM8_CHANNEL2
@ -1449,6 +1477,13 @@ config STM32L4_TIM8_CH2OUT
---help---
Enables channel 2 output.
config STM32L4_TIM8_CH2NOUT
bool "TIM8 Channel 2 Complementary Output"
default n
depends on STM32L4_TIM8_CH2OUT
---help---
Enables channel 2 complementary output.
endif # STM32L4_TIM8_CHANNEL2
config STM32L4_TIM8_CHANNEL3
@ -1472,6 +1507,13 @@ config STM32L4_TIM8_CH3OUT
---help---
Enables channel 3 output.
config STM32L4_TIM8_CH3NOUT
bool "TIM8 Channel 3 Complementary Output"
default n
depends on STM32L4_TIM8_CH3OUT
---help---
Enables channel 3 complementary output.
endif # STM32L4_TIM8_CHANNEL3
config STM32L4_TIM8_CHANNEL4
@ -1557,6 +1599,13 @@ config STM32L4_TIM15_CH1OUT
---help---
Enables channel 1 output.
config STM32L4_TIM15_CH1NOUT
bool "TIM15 Channel 1 Complementary Output"
default n
depends on STM32L4_TIM15_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_TIM15_CHANNEL1
config STM32L4_TIM15_CHANNEL2
@ -1642,6 +1691,13 @@ config STM32L4_TIM16_CH1OUT
---help---
Enables channel 1 output.
config STM32L4_TIM16_CH1NOUT
bool "TIM16 Channel 1 Complementary Output"
default n
depends on STM32L4_TIM16_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_TIM16_CHANNEL1
endif # STM32L4_PWM_MULTICHAN
@ -1704,6 +1760,13 @@ config STM32L4_TIM17_CH1OUT
---help---
Enables channel 1 output.
config STM32L4_TIM17_CH1NOUT
bool "TIM17 Channel 1 Complementary Output"
default n
depends on STM32L4_TIM17_CH1OUT
---help---
Enables channel 1 complementary output.
endif # STM32L4_TIM17_CHANNEL1
endif # STM32L4_PWM_MULTICHAN

View File

@ -128,6 +128,7 @@ struct stm32l4_pwmchan_s
uint8_t channel; /* Timer output channel: {1,..4} */
uint32_t pincfg; /* Output pin configuration */
enum stm32l4_chanmode_e mode;
uint32_t npincfg; /* Complementary output pin configuration (only TIM1/8 CH1-3)*/
};
/* This structure represents the state of one PWM timer */
@ -229,6 +230,7 @@ static struct stm32l4_pwmtimer_s g_pwm1dev =
.channel = 1,
.pincfg = PWM_TIM1_CH1CFG,
.mode = CONFIG_STM32L4_TIM1_CH1MODE,
.npincfg = PWM_TIM1_CH1NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM1_CHANNEL2
@ -236,6 +238,7 @@ static struct stm32l4_pwmtimer_s g_pwm1dev =
.channel = 2,
.pincfg = PWM_TIM1_CH2CFG,
.mode = CONFIG_STM32L4_TIM1_CH2MODE,
.npincfg = PWM_TIM1_CH2NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM1_CHANNEL3
@ -243,6 +246,7 @@ static struct stm32l4_pwmtimer_s g_pwm1dev =
.channel = 3,
.pincfg = PWM_TIM1_CH3CFG,
.mode = CONFIG_STM32L4_TIM1_CH3MODE,
.npincfg = PWM_TIM1_CH3NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM1_CHANNEL4
@ -250,6 +254,7 @@ static struct stm32l4_pwmtimer_s g_pwm1dev =
.channel = 4,
.pincfg = PWM_TIM1_CH4CFG,
.mode = CONFIG_STM32L4_TIM1_CH4MODE,
.npincfg = 0,
},
#endif
},
@ -275,6 +280,7 @@ static struct stm32l4_pwmtimer_s g_pwm2dev =
.channel = 1,
.pincfg = PWM_TIM2_CH1CFG,
.mode = CONFIG_STM32L4_TIM2_CH1MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM2_CHANNEL2
@ -282,6 +288,7 @@ static struct stm32l4_pwmtimer_s g_pwm2dev =
.channel = 2,
.pincfg = PWM_TIM2_CH2CFG,
.mode = CONFIG_STM32L4_TIM2_CH2MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM2_CHANNEL3
@ -289,6 +296,7 @@ static struct stm32l4_pwmtimer_s g_pwm2dev =
.channel = 3,
.pincfg = PWM_TIM2_CH3CFG,
.mode = CONFIG_STM32L4_TIM2_CH3MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM2_CHANNEL4
@ -296,6 +304,7 @@ static struct stm32l4_pwmtimer_s g_pwm2dev =
.channel = 4,
.pincfg = PWM_TIM2_CH4CFG,
.mode = CONFIG_STM32L4_TIM2_CH4MODE,
.npincfg = 0,
},
#endif
},
@ -321,6 +330,7 @@ static struct stm32l4_pwmtimer_s g_pwm3dev =
.channel = 1,
.pincfg = PWM_TIM3_CH1CFG,
.mode = CONFIG_STM32L4_TIM3_CH1MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM3_CHANNEL2
@ -328,6 +338,7 @@ static struct stm32l4_pwmtimer_s g_pwm3dev =
.channel = 2,
.pincfg = PWM_TIM3_CH2CFG,
.mode = CONFIG_STM32L4_TIM3_CH2MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM3_CHANNEL3
@ -335,6 +346,7 @@ static struct stm32l4_pwmtimer_s g_pwm3dev =
.channel = 3,
.pincfg = PWM_TIM3_CH3CFG,
.mode = CONFIG_STM32L4_TIM3_CH3MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM3_CHANNEL4
@ -342,6 +354,7 @@ static struct stm32l4_pwmtimer_s g_pwm3dev =
.channel = 4,
.pincfg = PWM_TIM3_CH4CFG,
.mode = CONFIG_STM32L4_TIM3_CH4MODE,
.npincfg = 0,
},
#endif
},
@ -367,6 +380,7 @@ static struct stm32l4_pwmtimer_s g_pwm4dev =
.channel = 1,
.pincfg = PWM_TIM4_CH1CFG,
.mode = CONFIG_STM32L4_TIM4_CH1MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM4_CHANNEL2
@ -374,6 +388,7 @@ static struct stm32l4_pwmtimer_s g_pwm4dev =
.channel = 2,
.pincfg = PWM_TIM4_CH2CFG,
.mode = CONFIG_STM32L4_TIM4_CH2MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM4_CHANNEL3
@ -381,6 +396,7 @@ static struct stm32l4_pwmtimer_s g_pwm4dev =
.channel = 3,
.pincfg = PWM_TIM4_CH3CFG,
.mode = CONFIG_STM32L4_TIM4_CH3MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM4_CHANNEL4
@ -388,6 +404,7 @@ static struct stm32l4_pwmtimer_s g_pwm4dev =
.channel = 4,
.pincfg = PWM_TIM4_CH4CFG,
.mode = CONFIG_STM32L4_TIM4_CH4MODE,
.npincfg = 0,
},
#endif
},
@ -413,6 +430,7 @@ static struct stm32l4_pwmtimer_s g_pwm5dev =
.channel = 1,
.pincfg = PWM_TIM5_CH1CFG,
.mode = CONFIG_STM32L4_TIM5_CH1MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM5_CHANNEL2
@ -420,6 +438,7 @@ static struct stm32l4_pwmtimer_s g_pwm5dev =
.channel = 2,
.pincfg = PWM_TIM5_CH2CFG,
.mode = CONFIG_STM32L4_TIM5_CH2MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM5_CHANNEL3
@ -427,6 +446,7 @@ static struct stm32l4_pwmtimer_s g_pwm5dev =
.channel = 3,
.pincfg = PWM_TIM5_CH3CFG,
.mode = CONFIG_STM32L4_TIM5_CH3MODE,
.npincfg = 0,
},
#endif
#ifdef CONFIG_STM32L4_TIM5_CHANNEL4
@ -434,6 +454,7 @@ static struct stm32l4_pwmtimer_s g_pwm5dev =
.channel = 4,
.pincfg = PWM_TIM5_CH4CFG,
.mode = CONFIG_STM32L4_TIM5_CH4MODE,
.npincfg = 0,
},
#endif
},
@ -459,6 +480,7 @@ static struct stm32l4_pwmtimer_s g_pwm8dev =
.channel = 1,
.pincfg = PWM_TIM8_CH1CFG,
.mode = CONFIG_STM32L4_TIM8_CH1MODE,
.npincfg = PWM_TIM8_CH1NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM8_CHANNEL2
@ -466,6 +488,7 @@ static struct stm32l4_pwmtimer_s g_pwm8dev =
.channel = 2,
.pincfg = PWM_TIM8_CH2CFG,
.mode = CONFIG_STM32L4_TIM8_CH2MODE,
.npincfg = PWM_TIM8_CH2NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM8_CHANNEL3
@ -473,6 +496,7 @@ static struct stm32l4_pwmtimer_s g_pwm8dev =
.channel = 3,
.pincfg = PWM_TIM8_CH3CFG,
.mode = CONFIG_STM32L4_TIM8_CH3MODE,
.npincfg = PWM_TIM8_CH3NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM8_CHANNEL4
@ -480,6 +504,7 @@ static struct stm32l4_pwmtimer_s g_pwm8dev =
.channel = 4,
.pincfg = PWM_TIM8_CH4CFG,
.mode = CONFIG_STM32L4_TIM8_CH4MODE,
.npincfg = 0,
},
#endif
},
@ -505,6 +530,7 @@ static struct stm32l4_pwmtimer_s g_pwm15dev =
.channel = 1,
.pincfg = PWM_TIM15_CH1CFG,
.mode = CONFIG_STM32L4_TIM15_CH1MODE,
.npincfg = PWM_TIM15_CH1NCFG,
},
#endif
#ifdef CONFIG_STM32L4_TIM15_CHANNEL2
@ -512,6 +538,7 @@ static struct stm32l4_pwmtimer_s g_pwm15dev =
.channel = 2,
.pincfg = PWM_TIM15_CH2CFG,
.mode = CONFIG_STM32L4_TIM15_CH2MODE,
.npincfg = 0,
},
#endif
},
@ -537,6 +564,7 @@ static struct stm32l4_pwmtimer_s g_pwm16dev =
.channel = 1,
.pincfg = PWM_TIM16_CH1CFG,
.mode = CONFIG_STM32L4_TIM16_CH1MODE,
.npincfg = PWM_TIM16_CH1NCFG,
},
#endif
},
@ -562,6 +590,7 @@ static struct stm32l4_pwmtimer_s g_pwm17dev =
.channel = 1,
.pincfg = PWM_TIM17_CH1CFG,
.mode = CONFIG_STM32L4_TIM17_CH1MODE,
.npincfg = PWM_TIM17_CH1NCFG,
},
#endif
},
@ -737,6 +766,7 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
/* New timer register bit settings */
uint16_t ccenable;
uint16_t ccnenable;
uint32_t ocmode1;
uint32_t ocmode2;
@ -967,6 +997,7 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
/* Handle channel specific setup */
ccenable = 0;
ccnenable = 0;
ocmode1 = 0;
ocmode2 = 0;
@ -976,6 +1007,7 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
{
ub16_t duty;
uint32_t chanmode;
uint32_t compout; /* Complementary output config */
bool ocmbit = false;
uint8_t channel;
#ifdef CONFIG_PWM_MULTICHAN
@ -1001,6 +1033,7 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
if (priv->channels[j].channel == channel)
{
mode = priv->channels[j].mode;
compout = priv->channels[j].npincfg;
break;
}
}
@ -1014,6 +1047,7 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
duty = info->duty;
channel = priv->channels[0].channel;
mode = priv->channels[0].mode;
compout = priv->channels[0].npincfg;
#endif
/* Duty cycle:
@ -1068,6 +1102,13 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
ccenable |= ATIM_CCER_CC1E;
/* Conditionnaly enable the complementary output */
if(compout)
{
ccnenable |= ATIM_CCER_CC1NE;
}
/* Set the CCMR1 mode values (leave CCMR2 zero) */
ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) |
@ -1091,6 +1132,13 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
ccenable |= ATIM_CCER_CC2E;
/* Conditionnaly enable the complementary output */
if(compout)
{
ccnenable |= ATIM_CCER_CC2NE;
}
/* Set the CCMR1 mode values (leave CCMR2 zero) */
ocmode1 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) |
@ -1114,6 +1162,13 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
ccenable |= ATIM_CCER_CC3E;
/* Conditionnaly enable the complementary output */
if(compout)
{
ccnenable |= ATIM_CCER_CC3NE;
}
/* Set the CCMR2 mode values (leave CCMR1 zero) */
ocmode2 |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) |
@ -1208,6 +1263,8 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | ATIM_CCER_CC2NE | ATIM_CCER_CC2NP |
ATIM_CCER_CC3NE | ATIM_CCER_CC3NP);
ccer |= ccnenable;
/* Reset the output compare and output compare N IDLE State */
cr2 &= ~(ATIM_CR2_OIS1 | ATIM_CR2_OIS1N | ATIM_CR2_OIS2 | ATIM_CR2_OIS2N |
@ -1223,9 +1280,23 @@ static int stm32l4pwm_timer(FAR struct stm32l4_pwmtimer_s *priv,
stm32l4pwm_putreg(priv, STM32L4_ATIM_BDTR_OFFSET, bdtr);
}
else
#if defined(CONFIG_STM32L4_TIM15_PWM) || defined(CONFIG_STM32L4_TIM15_PWM) || defined(CONFIG_STM32L4_TIM15_PWM)
if (priv->timtype == TIMTYPE_COUNTUP16)
{
/* Reset output N polarity level, output N state, output compare state,
* output compare N idle state.
*/
ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP);
ccer |= ccnenable;
}
else
#endif
#endif
{
ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP);
ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP); //Not sure why ??
}
/* Save the modified register values */
@ -1646,14 +1717,24 @@ static int stm32l4pwm_setup(FAR struct pwm_lowerhalf_s *dev)
for (i = 0; i < PWM_NCHANNELS; i++)
{
pincfg = priv->channels[i].pincfg;
if (pincfg == 0)
if (pincfg != 0)
{
continue;
pwminfo("pincfg: %08x\n", pincfg);
stm32l4_configgpio(pincfg);
}
pwminfo("pincfg: %08x\n", pincfg);
stm32l4_configgpio(pincfg);
/* Enable complementary channel if available */
pincfg = priv->channels[i].npincfg;
if (pincfg != 0)
{
pwminfo("npincfg: %08x\n", pincfg);
stm32l4_configgpio(pincfg);
}
pwm_dumpgpio(pincfg, "PWM setup");
}
@ -1697,18 +1778,29 @@ static int stm32l4pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
for (i = 0; i < PWM_NCHANNELS; i++)
{
pincfg = priv->channels[i].pincfg;
if (pincfg == 0)
if (pincfg != 0)
{
continue;
pwminfo("pincfg: %08x\n", pincfg);
pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK);
pincfg |= GPIO_INPUT | GPIO_FLOAT;
stm32l4_configgpio(pincfg);
}
pwminfo("pincfg: %08x\n", pincfg);
pincfg = priv->channels[i].npincfg;
if (pincfg != 0)
{
pwminfo("npincfg: %08x\n", pincfg);
pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK);
pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK);
pincfg |= GPIO_INPUT | GPIO_FLOAT;
pincfg |= GPIO_INPUT | GPIO_FLOAT;
stm32l4_configgpio(pincfg);
}
stm32l4_configgpio(pincfg);
}
return OK;

View File

@ -114,6 +114,11 @@
# else
# define PWM_TIM1_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM1_CH1NOUT
# define PWM_TIM1_CH1NCFG GPIO_TIM1_CH1NOUT
# else
# define PWM_TIM1_CH1NCFG 0
# endif
# define PWM_TIM1_CHANNEL1 1
#else
# define PWM_TIM1_CHANNEL1 0
@ -124,6 +129,11 @@
# else
# define PWM_TIM1_CH2CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM1_CH2NOUT
# define PWM_TIM1_CH2NCFG GPIO_TIM1_CH2NOUT
# else
# define PWM_TIM1_CH2NCFG 0
# endif
# define PWM_TIM1_CHANNEL2 1
#else
# define PWM_TIM1_CHANNEL2 0
@ -134,6 +144,11 @@
# else
# define PWM_TIM1_CH3CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM1_CH3NOUT
# define PWM_TIM1_CH3NCFG GPIO_TIM1_CH3NOUT
# else
# define PWM_TIM1_CH3NCFG 0
# endif
# define PWM_TIM1_CHANNEL3 1
#else
# define PWM_TIM1_CHANNEL3 0
@ -329,6 +344,11 @@
# else
# define PWM_TIM8_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM8_CH1OUT
# define PWM_TIM8_CH1NCFG GPIO_TIM8_CH1NOUT
# else
# define PWM_TIM8_CH1NCFG 0
# endif
# define PWM_TIM8_CHANNEL1 1
#else
# define PWM_TIM8_CHANNEL1 0
@ -339,6 +359,11 @@
# else
# define PWM_TIM8_CH2CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM8_CH2NOUT
# define PWM_TIM8_CH2NCFG GPIO_TIM8_CH2NOUT
# else
# define PWM_TIM8_CH2NCFG 0
# endif
# define PWM_TIM8_CHANNEL2 1
#else
# define PWM_TIM8_CHANNEL2 0
@ -349,6 +374,11 @@
# else
# define PWM_TIM8_CH3CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM8_CH3NOUT
# define PWM_TIM8_CH3NCFG GPIO_TIM8_CH3NOUT
# else
# define PWM_TIM8_CH3NCFG 0
# endif
# define PWM_TIM8_CHANNEL3 1
#else
# define PWM_TIM8_CHANNEL3 0
@ -372,6 +402,11 @@
# else
# define PWM_TIM15_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM15_CH1NOUT
# define PWM_TIM15_CH1NCFG GPIO_TIM15_CH1NOUT
# else
# define PWM_TIM15_CH1NCFG 0
# endif
# define PWM_TIM15_CHANNEL1 1
#else
# define PWM_TIM15_CHANNEL1 0
@ -394,6 +429,11 @@
# else
# define PWM_TIM16_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM16_CH1NOUT
# define PWM_TIM16_CH1NCFG GPIO_TIM16_CH1NOUT
# else
# define PWM_TIM16_CH1NCFG 0
# endif
# define PWM_TIM16_CHANNEL1 1
#else
# define PWM_TIM16_CHANNEL1 0
@ -406,6 +446,11 @@
# else
# define PWM_TIM17_CH1CFG 0
# endif
# ifdef CONFIG_STM32L4_TIM17_CH1NOUT
# define PWM_TIM17_CH1NCFG GPIO_TIM17_CH1NOUT
# else
# define PWM_TIM17_CH1NCFG 0
# endif
# define PWM_TIM17_CHANNEL1 1
#else
# define PWM_TIM17_CHANNEL1 0

View File

@ -212,6 +212,18 @@
#define GPIO_TIM2_CH1IN GPIO_TIM2_CH1IN_1
#define GPIO_TIM2_CH2IN GPIO_TIM2_CH2IN_1
/* PWM output for full bridge, uses config 1, because port E is N/A on QFP64
* CH1 | 1(A8) 2(E9)
* CH2 | 1(A9) 2(E11)
* CHN1 | 1(A7) 2(B13) 3(E8)
* CHN2 | 1(B0) 2(B14) 3(E10)
*/
#define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_1
#define GPIO_TIM1_CH1NOUT GPIO_TIM1_CH1N_1
#define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_1
#define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_1
/************************************************************************************
* Public Data
************************************************************************************/

View File

@ -66,6 +66,10 @@ ifeq ($(CONFIG_QENCODER),y)
CSRCS += stm32_qencoder.c
endif
ifeq ($(CONFIG_PWM),y)
CSRCS += stm32_pwm.c
endif
ifeq ($(CONFIG_LIB_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif

View File

@ -207,3 +207,24 @@ int board_app_initialize(uintptr_t arg)
return OK;
}
#ifdef CONFIG_BOARDCTL_IOCTL
int board_ioctl(unsigned int cmd, uintptr_t arg)
{
return -ENOTTY;
}
#endif
#if defined(CONFIG_BOARDCTL_UNIQUEID)
int board_uniqueid(uint8_t *uniqueid)
{
if (uniqueid == 0)
{
return -EINVAL;
}
stm32l4_get_uniqueid(uniqueid);
return OK;
}
#endif

View File

@ -0,0 +1,275 @@
/************************************************************************************
* configs/nucleo-l476rg/src/stm32_pwm.c
*
* Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
*
* 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 NuttX 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 OWNER 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.
*
************************************************************************************/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/board.h>
#include <nuttx/drivers/pwm.h>
#include <arch/board/board.h>
#include "chip.h"
#include "up_arch.h"
#include "stm32l4_pwm.h"
#include "nucleo-l476rg.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Configuration *******************************************************************/
/* PWM
*
* The STM3240G-Eval has no real on-board PWM devices, but the board can be
* configured to output a pulse train using variously unused pins on the board for
* PWM output (see board.h for details of pins).
*/
#ifdef CONFIG_PWM
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: board_pwm_setup
*
* Description:
* All STM32L4 architectures must provide the following interface to work with
* examples/pwm.
*
************************************************************************************/
int board_pwm_setup(void)
{
static bool initialized = false;
struct pwm_lowerhalf_s *pwm;
int ret;
/* Have we already initialized? */
if (!initialized)
{
/* Call stm32l4_pwminitialize() to get an instance of the PWM interface */
/* PWM
*
* The Nucleo-l476rg has no real on-board PWM devices, but the board can be
* configured to output a pulse train using TIM1 or 8, or others (see board.h).
* Let's figure out which the user has configured.
*/
# if defined(CONFIG_STM32L4_TIM1_PWM)
pwm = stm32l4_pwminitialize(1);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm0" */
ret = pwm_register("/dev/pwm0", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM2_PWM)
pwm = stm32l4_pwminitialize(2);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm1" */
ret = pwm_register("/dev/pwm1", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM3_PWM)
pwm = stm32l4_pwminitialize(3);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm2" */
ret = pwm_register("/dev/pwm2", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM4_PWM)
pwm = stm32l4_pwminitialize(4);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm3" */
ret = pwm_register("/dev/pwm3", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM5_PWM)
pwm = stm32l4_pwminitialize(5);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm4" */
ret = pwm_register("/dev/pwm4", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM8_PWM)
pwm = stm32l4_pwminitialize(8);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm5" */
ret = pwm_register("/dev/pwm5", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM15_PWM)
pwm = stm32l4_pwminitialize(15);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm6" */
ret = pwm_register("/dev/pwm6", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM16_PWM)
pwm = stm32l4_pwminitialize(16);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm7" */
ret = pwm_register("/dev/pwm7", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
# if defined(CONFIG_STM32L4_TIM17_PWM)
pwm = stm32l4_pwminitialize(17);
if (!pwm)
{
aerr("ERROR: Failed to get the STM32L4 PWM lower half\n");
return -ENODEV;
}
/* Register the PWM driver at "/dev/pwm8" */
ret = pwm_register("/dev/pwm8", pwm);
if (ret < 0)
{
aerr("ERROR: pwm_register failed: %d\n", ret);
return ret;
}
#endif
/* Now we are initialized */
initialized = true;
}
return OK;
}
#endif /* CONFIG_PWM */