Blame view

RIOT/drivers/include/periph/pwm.h 5.82 KB
a752c7ab   elopes   add first test an...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  /*
   * Copyright (C) 2014-2015 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.
   */
  
  /**
   * @defgroup    drivers_periph_pwm PWM
   * @ingroup     drivers_periph
   * @brief       Low-level PWM peripheral driver
   *
   * This interface enables access to CPU peripherals generating PWM signals. On
   * most platforms, this interface will be implemented based on hardware timers,
   * though some CPUs provide dedicated PWM peripherals.
   *
   * The characteristics of a PWM signal can be defined by three basic parameters,
   * namely the frequency, the duty cycle, and the operational mode. This
   * interface supports basic PWM generation in left-aligned, right-aligned, and
   * center mode. Additionally the interface supports the definition of the used
   * resolution, defining the granularity with which one can specify the duty
   * cycle. This brings more flexibility to the configuration of the frequency,
   * especially on systems with low system clocks.
   *
   * Typically, a single PWM device (e.g. hardware timer) supports PWM signal
   * generation on multiple pins in parallel. While the duty cycle is selectable
   * for each channel individually, the frequency and resolution are shared for
   * all channels.
   *
   * The mapping/configuration of PWM devices (timers) and the used pins has to be
   * done in the board configuration (the board's `periph_conf.h).
   *
   * When using the PWM interface, first thing you have to do is initialize the
   * PWM device with the targeted mode, frequency, and resolution settings. Once
   * the device is initialized, it will start the generation of PWM signals on all
   * configured pins immediately, with an initial duty cycle of `0`. Use the
   * pwm_set() function to change the duty cycle for a given channel. If you
   * want to disable the PWM generation again, simply call pwm_poweroff().
   *
   * ## (Low-)Power implications
   *
   * After initialization, the a PWM peripheral **should** be powered on and
   * active. When manually stopped using the pwm_poweroff() function, the PWM
   * generation **should** be stopped for all channels and the PWM peripheral
   * **should** be fully power off (e.g. through peripheral clock gating). Once
   * being re-enabled by calling the pwm_poweron() function, the PWM peripheral
   * **should** transparently continue its previously configured operation,
   * including the last active duty cycle values.
   *
   * While a PWM device is active, some implementations might need to block
   * certain power modes.
   *
   * @{
   * @file
   * @brief       Low-level PWM peripheral driver interface definitions
   *
   * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
   */
  
  #ifndef PERIPH_PWM_H
  #define PERIPH_PWM_H
  
  #include <stdint.h>
  #include <limits.h>
  
  #include "periph_cpu.h"
  #include "periph_conf.h"
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /**
   * @brief   Default PWM access macro
   */
  #ifndef PWM_DEV
  #define PWM_DEV(x)          (x)
  #endif
  
  /**
   * @brief  Default PWM undefined value
   */
  #ifndef PWM_UNDEF
  #define PWM_UNDEF           (UINT_MAX)
  #endif
  
  /**
   * @brief   Default PWM type definition
   */
  #ifndef HAVE_PWM_T
  typedef unsigned int pwm_t;
  #endif
  
  /**
   * @brief   Default PWM mode definition
   */
  #ifndef HAVE_PWM_MODE_T
  typedef enum {
      PWM_LEFT,           /*< use left aligned PWM */
      PWM_RIGHT,          /*< use right aligned PWM */
      PWM_CENTER          /*< use center aligned PWM */
  } pwm_mode_t;
  #endif
  
  /**
   * @brief   Initialize a PWM device
   *
   * The PWM module is based on virtual PWM devices, which can have one or more
   * channels. The PWM devices can be configured to run with a given frequency and
   * resolution, which are always identical for the complete device, hence for
   * every channel on a device.
   *
   * The desired frequency and resolution may not be possible on a given device
   * when chosen too large. In this case the PWM driver will always keep the
   * resolution and decrease the frequency if needed. To verify the correct
   * settings compare the returned value which is the actually set frequency.
   *
   * @param[in] dev           PWM device to initialize
   * @param[in] mode          PWM mode, left, right or center aligned
   * @param[in] freq          PWM frequency in Hz
   * @param[in] res           PWM resolution
   *
   * @return                  actual PWM frequency on success
   * @return                  0 on error
   */
  uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res);
  
  /**
   * @brief   Get the number of available channels
   *
   * @param[in] dev           PWM device
   *
   * @return                  Number of channels available for the given device
   */
  uint8_t pwm_channels(pwm_t dev);
  
  /**
   * @brief   Set the duty-cycle for a given channel of the given PWM device
   *
   * The duty-cycle is set in relation to the chosen resolution of the given
   * device. If value > resolution, value is set to resolution.
   *
   * @param[in] dev           the PWM device to set
   * @param[in] channel       the channel of the given device to set
   * @param[in] value         the desired duty-cycle to set
   */
  void pwm_set(pwm_t dev, uint8_t channel, uint16_t value);
  
  /**
   * @brief   Resume PWM generation on the given device
   *
   * When this function is called, the given PWM device is powered on and
   * continues its previously configured operation. The duty cycle of each channel
   * will be the value that was last set.
   *
   * This function must not be called before the PWM device was initialized.
   *
   * @param[in] dev           device to start
   */
  void pwm_poweron(pwm_t dev);
  
  /**
   * @brief   Stop PWM generation on the given device
   *
   * This function stops the PWM generation on all configured channels for the
   * given device and powers down the given PWM peripheral.
   *
   * @param[in] dev           device to stop
   */
  void pwm_poweroff(pwm_t dev);
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* PERIPH_PWM_H */
  /** @} */