15 #if (RUUVI_NRF5_SDK15_GPIO_PWM_ENABLED || DOXYGEN || CEEDLING)
21 #include "nrf_drv_pwm.h"
23 #define RI_GPIO_PWM_DRIVER 0
24 #define RI_GPIO_PWM_PLAYBACK_OK (0)
25 #define RI_GPIO_PWM_PLAYBACK_COUNT (1)
26 #define RI_GPIO_PWM_DRIVER_PIN_POINT (0)
27 #define RI_GPIO_PWM_SEQ_DELAY (0)
28 #define RI_GPIO_PWM_SEQ_REPEATS (1)
30 #define RI_GPIO_PWM_MAX_FREQ (16000000.00f)
31 #define RI_GPIO_PWM_MIN_FREQ (2.00f)
33 #define RI_GPIO_PWM_MAX_DUTY (1.00f)
34 #define RI_GPIO_PWM_MIN_DUTY (0.00f)
36 #define RI_GPIO_PWM_CHANNEL_UNUSED (0)
38 #define RI_GPIO_PWM_MIN_TOP_VALUE (1U)
39 #define RI_GPIO_PWM_MIN_REST_FOR_TOP (0.999999f)
41 #define RI_GPIO_PWM_FREQ_COUNT (8)
43 #define RI_GPIO_PWM_BASE_FREQ_16MHZ (RI_GPIO_PWM_MAX_FREQ)
44 #define RI_GPIO_PWM_BASE_FREQ_8MHZ (8000000.00f)
45 #define RI_GPIO_PWM_BASE_FREQ_4MHZ (4000000.00f)
46 #define RI_GPIO_PWM_BASE_FREQ_2MHZ (2000000.00f)
47 #define RI_GPIO_PWM_BASE_FREQ_1MHZ (1000000.00f)
48 #define RI_GPIO_PWM_BASE_FREQ_500KHZ (500000.00f)
49 #define RI_GPIO_PWM_BASE_FREQ_250KHZ (250000.00f)
50 #define RI_GPIO_PWM_BASE_FREQ_125KHZ (125000.00f)
53 static bool m_gpio_pwm_is_init =
false;
54 static bool m_gpio_pwm_is_start =
false;
86 if (!m_gpio_pwm_is_init)
88 m_gpio_pwm_is_init =
true;
99 if (
false == m_gpio_pwm_is_init)
105 m_gpio_pwm_is_init =
false;
114 return m_gpio_pwm_is_init;
117 static bool ri_gpio_pwm_is_start (
void)
119 return m_gpio_pwm_is_start;
126 static inline uint8_t ruuvi_to_nrf_pin_pwm_map (
const ri_gpio_id_t pin)
128 return ( (pin >> 3) & 0xE0) + (pin & 0x1F);
131 static nrf_pwm_clk_t ruuvi_get_base_config (
float *
const frequency,
132 float *
const duty_cycle,
135 nrf_pwm_clk_t clock = NRF_PWM_CLK_16MHz;
137 float m_freq = (*frequency);
138 float m_duty = (*duty_cycle);
143 if (freq[i] >= m_freq)
145 float f_rest = (freq[i] / m_freq) -
146 (uint32_t) (freq[i] / m_freq);
148 if (f_rest_min >= f_rest)
150 m_top = (freq[i] / m_freq) * m_duty;
155 clock = (nrf_pwm_clk_t) i;
156 (*p_top) = (freq[i] / m_freq);
166 float *
const frequency,
float *
const duty_cycle)
173 if (
true == ri_gpio_pwm_is_start ())
181 if ( (duty_cycle == NULL) || (frequency == NULL))
199 nrf_pwm_clk_t clock = ruuvi_get_base_config (frequency, duty_cycle, &top);
200 uint8_t out_pin = (ruuvi_to_nrf_pin_pwm_map (pin) | NRF_DRV_PWM_PIN_INVERTED);
201 nrf_drv_pwm_config_t config = NRF_DRV_PWM_DEFAULT_CONFIG;
203 config.base_clock = clock;
204 config.top_value = top;
207 (NRF_SUCCESS == nrf_drv_pwm_init (&m_pwm, &config, NULL)))
209 uint16_t steps_duty = (uint16_t) (top * (*duty_cycle));
210 static nrf_pwm_values_individual_t seq_values;
211 seq_values.channel_0 = steps_duty;
215 nrf_pwm_sequence_t
const seq =
217 .values.p_individual = &seq_values,
218 .length = NRF_PWM_VALUES_LENGTH (seq_values),
225 NRF_DRV_PWM_FLAG_LOOP))
228 m_gpio_pwm_is_start =
true;
243 if (
true == nrf_drv_pwm_stop (&m_pwm, wait))
245 nrf_drv_pwm_uninit (&m_pwm);
246 m_gpio_pwm_is_start =
false;
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RI_GPIO_PWM_MIN_DUTY
#define RI_GPIO_PWM_BASE_FREQ_4MHZ
#define RI_GPIO_PWM_MIN_TOP_VALUE
#define RI_GPIO_PWM_PLAYBACK_OK
#define RI_GPIO_PWM_CHANNEL_UNUSED
#define RI_GPIO_PWM_PLAYBACK_COUNT
#define RI_GPIO_PWM_MAX_DUTY
#define RI_GPIO_PWM_BASE_FREQ_500KHZ
#define RI_GPIO_PWM_SEQ_REPEATS
#define RI_GPIO_PWM_MIN_REST_FOR_TOP
bool ri_gpio_is_init(void)
return true if GPIO is init, false otherwise.
rd_status_t ri_gpio_configure(const ri_gpio_id_t pin, const ri_gpio_mode_t mode)
Configure a pin of a port into a mode. If there are several ports the platform driver must implement ...
rd_status_t ri_gpio_pwm_stop(const ri_gpio_id_t pin)
Stop PWM on given pin.
#define RI_GPIO_PWM_MIN_FREQ
#define RI_GPIO_PWM_BASE_FREQ_2MHZ
#define RI_GPIO_PWM_DRIVER
#define RI_GPIO_PWM_BASE_FREQ_125KHZ
#define RI_GPIO_PWM_MAX_FREQ
bool ri_gpio_pwm_is_init(void)
Check if PWM is initialized.
#define RI_GPIO_PWM_BASE_FREQ_250KHZ
#define RI_GPIO_PWM_SEQ_DELAY
#define RI_GPIO_PWM_BASE_FREQ_8MHZ
#define RI_GPIO_PWM_FREQ_COUNT
#define RI_GPIO_PWM_DRIVER_PIN_POINT
rd_status_t ri_gpio_pwm_init(void)
Run any necessary initialization for PWM.
#define RI_GPIO_PWM_BASE_FREQ_16MHZ
rd_status_t ri_gpio_pwm_start(const ri_gpio_id_t pin, const ri_gpio_mode_t mode, float *const frequency, float *const duty_cycle)
Start PWM on given pin at given frequency and duty cycle.
rd_status_t ri_gpio_pwm_uninit(void)
Uninitialize PWM.
#define RI_GPIO_PWM_BASE_FREQ_1MHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_500KHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_8MHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_1MHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_125KHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_250KHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_2MHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_4MHZ
@ RI_GPIO_PWM_BASE_NUM_FREQ_16MHZ
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
uint16_t ri_gpio_id_t
port<<8 + pin
@ RI_GPIO_MODE_OUTPUT_STANDARD
Push-pull output, can be written.
@ RI_GPIO_MODE_OUTPUT_HIGHDRIVE
Push-pull output, can be written. Higher current drive than standard.