1 /* Copyright 2020 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
7 /*! @brief Enums for PWM running modes. */
9 METAL_PWM_CONTINUOUS = 0,
10 METAL_PWM_ONE_SHOT = 1
11 } metal_pwm_run_mode_t;
13 /*! @brief Enums for Phase correct PWM. */
15 METAL_PWM_PHASE_CORRECT_DISABLE = 0,
16 METAL_PWM_PHASE_CORRECT_ENABLE = 1,
17 } metal_pwm_phase_correct_t;
19 /*! @brief Enums for Interrupts enable/disable. */
21 METAL_PWM_INTERRUPT_DISABLE = 0,
22 METAL_PWM_INTERRUPT_ENABLE = 1,
23 } metal_pwm_interrupt_t;
27 /*! @brief vtable for PWM. */
28 struct metal_pwm_vtable {
29 int (*enable)(struct metal_pwm *pwm);
30 int (*disable)(struct metal_pwm *pwm);
31 int (*set_freq)(struct metal_pwm *pwm, unsigned int idx, unsigned int freq);
32 int (*set_duty)(struct metal_pwm *pwm, unsigned int idx, unsigned int duty,
33 metal_pwm_phase_correct_t phase_corr);
34 unsigned int (*get_duty)(struct metal_pwm *pwm, unsigned int idx);
35 unsigned int (*get_freq)(struct metal_pwm *pwm, unsigned int idx);
36 int (*trigger)(struct metal_pwm *pwm, unsigned int idx,
37 metal_pwm_run_mode_t mode);
38 int (*stop)(struct metal_pwm *pwm, unsigned int idx);
39 int (*cfg_interrupt)(struct metal_pwm *pwm, metal_pwm_interrupt_t flag);
40 int (*clr_interrupt)(struct metal_pwm *pwm, unsigned int idx);
41 struct metal_interrupt *(*get_interrupt_controller)(struct metal_pwm *pwm);
42 int (*get_interrupt_id)(struct metal_pwm *pwm, unsigned int idx);
45 /*! @brief A handle for a PWM device. */
47 const struct metal_pwm_vtable *vtable;
50 /*! @brief Gets a PWM device handle.
51 * @param device_num The index of the desired PWM device.
52 * @return A handle to the PWM device, or NULL if the device does not exist.*/
53 struct metal_pwm *metal_pwm_get_device(unsigned int device_num);
55 /*! @brief Enables PWM operation.
56 * @param pwm The handle for the PWM device to initialize.
57 * @return 0 If no error.*/
58 inline int metal_pwm_enable(struct metal_pwm *pwm) {
59 return pwm->vtable->enable(pwm);
62 /*! @brief Disables PWM operation.
63 * @param pwm The handle for the PWM device to be disabled.
64 * @return 0 If no error.*/
65 inline int metal_pwm_disable(struct metal_pwm *pwm) {
66 return pwm->vtable->disable(pwm);
69 /*! @brief Sets frequency in Hz for a given PWM instance.
70 * @param pwm PWM device handle.
71 * @param idx PWM channel id.
72 * @param freq PWM frequency in Hz.
73 * @return 0 If no error.*/
74 inline int metal_pwm_set_freq(struct metal_pwm *pwm, unsigned int idx,
76 return pwm->vtable->set_freq(pwm, idx, freq);
79 /*! @brief Sets duty cycle in percent values [0 - 100] for a given PWM instance.
80 * Phase correct mode provides center aligned PWM waveform output.
81 * @param pwm PWM device handle.
82 * @param idx PWM channel id.
83 * @param duty PWM duty cycle value.
84 * @param phase_corr Enable / Disable phase correct mode.
85 * @return 0 If no error.*/
86 inline int metal_pwm_set_duty(struct metal_pwm *pwm, unsigned int idx,
88 metal_pwm_phase_correct_t phase_corr) {
89 return pwm->vtable->set_duty(pwm, idx, duty, phase_corr);
92 /*! @brief Gets duty cycle in percent values [0 - 100] for a given PWM instance.
93 * @param pwm PWM device handle.
94 * @param idx PWM channel id.
95 * @return PWM duty cycle value.*/
96 inline unsigned int metal_pwm_get_duty(struct metal_pwm *pwm,
98 return pwm->vtable->get_duty(pwm, idx);
101 /*! @brief Gets frequency in Hz for a given PWM instance.
102 * @param pwm PWM device handle.
103 * @param idx PWM channel id.
104 * @return PWM frequency in Hz.*/
105 inline unsigned int metal_pwm_get_freq(struct metal_pwm *pwm,
107 return pwm->vtable->get_freq(pwm, idx);
110 /*! @brief Starts a PWM instance in selected run mode (continuous/one shot).
111 * @param pwm PWM device handle.
112 * @param idx PWM channel id.
113 * @return 0 If no error.*/
114 inline int metal_pwm_trigger(struct metal_pwm *pwm, unsigned int idx,
115 metal_pwm_run_mode_t mode) {
116 return pwm->vtable->trigger(pwm, idx, mode);
119 /*! @brief Stops a running PWM instance in continuous mode.
120 * @param pwm PWM device handle.
121 * @param idx PWM channel id.
122 * @return 0 If no error.*/
123 inline int metal_pwm_stop(struct metal_pwm *pwm, unsigned int idx) {
124 return pwm->vtable->stop(pwm, idx);
127 /*! @brief Enable or Disable PWM interrupts.
128 * @param pwm PWM device handle.
129 * @param flag PWM interrupt enable flag.
130 * @return 0 If no error.*/
131 inline int metal_pwm_cfg_interrupt(struct metal_pwm *pwm,
132 metal_pwm_interrupt_t flag) {
133 return pwm->vtable->cfg_interrupt(pwm, flag);
136 /*! @brief Clears pending interrupt flags.
137 * @param pwm PWM device handle.
138 * @param idx PWM channel id.
139 * @return 0 If no error.*/
140 inline int metal_pwm_clr_interrupt(struct metal_pwm *pwm, unsigned int idx) {
141 return pwm->vtable->clr_interrupt(pwm, idx);
144 /*! @brief Get the interrupt controller of the PWM peripheral.
145 * The interrupt controller must be initialized before any interrupts can be
146 * registered or enabled with it.
147 * @param pwm PWM device handle.
148 * @return The handle for the PWM interrupt controller.*/
149 inline struct metal_interrupt *
150 metal_pwm_interrupt_controller(struct metal_pwm *pwm) {
151 return pwm->vtable->get_interrupt_controller(pwm);
154 /*! @brief Get the interrupt ID of the PWM peripheral.
155 * @param pwm PWM device handle.
156 * @param idx PWM channel id.
157 * @return The PWM interrupt id.*/
158 inline int metal_pwm_get_interrupt_id(struct metal_pwm *pwm, unsigned int idx) {
159 return pwm->vtable->get_interrupt_id(pwm, idx);