[sw/lib/pwm] add support for setting PWM polarity

This commit is contained in:
Henrik Brix Andersen 2025-04-12 19:52:20 +00:00
parent 99ab37dae4
commit f703dedf86
2 changed files with 22 additions and 1 deletions

View file

@ -14,6 +14,7 @@
#ifndef NEORV32_PWM_H
#define NEORV32_PWM_H
#include <stdbool.h>
#include <stdint.h>
@ -36,6 +37,7 @@ enum CHANNEL_CFG_enum {
PWM_CFG_CDIV_LSB = 8, /**< PWM configuration register(8) (r/w): Clock divider (10-bit), LSB */
PWM_CFG_CDIV_MSB = 17, /**< PWM configuration register(17) (r/w): Clock divider (10-bit), MSB */
PWM_CFG_POL = 27, /**< PWM configuration register(27) (r/w): Channel polarity, inverted when set */
PWM_CFG_PRSC_LSB = 28, /**< PWM configuration register(28) (r/w): Clock prescaler select (3-bit), LSB */
PWM_CFG_PRSC_MSB = 30, /**< PWM configuration register(30) (r/w): Clock prescaler select (3-bit), MSB */
PWM_CFG_EN = 31 /**< PWM configuration register(31) (r/w): channel enable */
@ -51,6 +53,7 @@ int neorv32_pwm_available(void);
int neorv32_pmw_get_num_channels(void);
void neorv32_pwm_ch_enable(int channel);
void neorv32_pwm_ch_disable(int channel);
void neorv32_pwm_ch_set_polarity(int channel, bool inverted);
void neorv32_pwm_ch_set_clock(int channel, int prsc, int cdiv);
void neorv32_pwm_ch_set_duty(int channel, int duty);
/**@}*/

View file

@ -80,6 +80,24 @@ void neorv32_pwm_ch_disable(int channel) {
}
/**********************************************************************//**
* Set PWM channel's polarity configuration.
*
* @param[in] channel Channel select (0..15).
* @param[in] normal polarity if false (default), inverted polarity if true
**************************************************************************/
void neorv32_pwm_ch_set_polarity(int channel, bool inverted) {
channel &= 0xf; // constrain range
if (inverted) {
NEORV32_PWM->CHANNEL_CFG[channel] |= ((uint32_t)(1 << PWM_CFG_POL));
} else {
NEORV32_PWM->CHANNEL_CFG[channel] &= ~((uint32_t)(1 << PWM_CFG_POL));
}
}
/**********************************************************************//**
* Set PWM channel's clock configuration.
*
@ -92,7 +110,7 @@ void neorv32_pwm_ch_set_clock(int channel, int prsc, int cdiv) {
channel &= 0xf; // constrain range
uint32_t tmp = NEORV32_PWM->CHANNEL_CFG[channel];
tmp &= 0x800000ffU; // clear current prsc and cdiv, keep enable and duty
tmp &= 0x880000ffU; // clear current prsc and cdiv, keep enable, polarity, and duty
tmp |= ((uint32_t)(prsc & 0x7U)) << PWM_CFG_PRSC_LSB;
tmp |= ((uint32_t)(cdiv & 0x3ffU)) << PWM_CFG_CDIV_LSB;
NEORV32_PWM->CHANNEL_CFG[channel] = tmp;