]> begriffs open source - cmsis-freertos/blob - Demo/CORTEX_M4_SimpleLink_CC3220SF_CCS/ti/drivers/PWM.h
Updated to FreeRTOS V10.0.1
[cmsis-freertos] / Demo / CORTEX_M4_SimpleLink_CC3220SF_CCS / ti / drivers / PWM.h
1 /*
2  * Copyright (c) 2015-2016, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       PWM.h
34  *  @brief      PWM driver interface
35  *
36  *  To use the PWM driver, ensure that the correct driver library for your
37  *  device is linked in and include this header file as follows:
38  *  @code
39  *  #include <ti/drivers/PWM.h>
40  *  @endcode
41  *
42  *  This module serves as the main interface for applications.  Its purpose
43  *  is to redirect the PWM APIs to specific driver implementations
44  *  which are specified using a pointer to a #PWM_FxnTable.
45  *
46  *  # Overview #
47  *  The PWM driver in TI-RTOS facilitates the generation of Pulse Width
48  *  Modulated signals via simple and portable APIs.  PWM instances must be
49  *  opened by calling PWM_open() while passing in a PWM index and a parameters
50  *  data structure.
51  *
52  *  The driver APIs serve as an interface to a typical TI-RTOS application.
53  *  The specific peripheral implementations are responsible for creating all OS
54  *  specific primitives to allow for thread-safe operation.
55  *
56  *  When a PWM instance is opened, the period, duty cycle and idle level are
57  *  configured and the PWM is stopped (waveforms not generated until PWM_start()
58  *  is called).  The maximum period and duty supported is device dependent;
59  *  refer to the implementation specific documentation for values.
60  *
61  *  PWM outputs are active-high, meaning the duty will control the duration of
62  *  high output on the pin (at 0% duty, the output is always low, at 100% duty,
63  *  the output is always high).
64  *
65  *  # Usage #
66  *
67  *  @code
68  *    PWM_Handle pwm;
69  *    PWM_Params pwmParams;
70  *
71  *    // Initialize the PWM driver.
72  *    PWM_init();
73  *
74  *    // Initialize the PWM parameters
75  *    PWM_Params_init(&pwmParams);
76  *    pwmParams.idleLevel = PWM_IDLE_LOW;      // Output low when PWM is not running
77  *    pwmParams.period.unit = PWM_PERIOD_HZ;   // Period is in Hz
78  *    pwmParams.period.value = 1e6;            // 1MHz
79  *    pwmParams.duty.unit = PWM_DUTY_FRACTION; // Duty is in fractional percentage
80  *    pwmParams.duty.value = 0;                // 0% initial duty cycle
81  *
82  *    // Open the PWM instance
83  *    pwm = PWM_open(Board_PWM0, &pwmParams);
84  *
85  *    if (pwm == NULL) {
86  *        // PWM_open() failed
87  *        while (1);
88  *    }
89  *
90  *    PWM_start(handle);                       // start PWM with 0% duty cycle
91  *
92  *    PWM_setDuty(pwm,
93  *         (PWM_DUTY_FRACTION_MAX / 2));       // set duty cycle to 50%
94  *  @endcode
95  *
96  *  Details for the example code above are described in the following
97  *  subsections.
98  *
99  *  ### PWM Driver Configuration #
100  *
101  *  In order to use the PWM APIs, the application is required
102  *  to provide device-specific PWM configuration in the Board.c file.
103  *  The PWM driver interface defines a configuration data structure:
104  *
105  *  @code
106  *  typedef struct PWM_Config_ {
107  *      PWM_FxnTable const    *fxnTablePtr;
108  *      void                  *object;
109  *      void         const    *hwAttrs;
110  *  } PWM_Config;
111  *  @endcode
112  *
113  *  The application must declare an array of PWM_Config elements, named
114  *  PWM_config[].  Each element of PWM_config[] is populated with
115  *  pointers to a device specific PWM driver implementation's function
116  *  table, driver object, and hardware attributes.  The hardware attributes
117  *  define properties such as which pin will be driven, and which timer peripheral
118  *  will be used.  Each element in PWM_config[] corresponds to
119  *  a PWM instance, and none of the elements should have NULL pointers.
120  *
121  *  Additionally, the PWM driver interface defines a global integer variable
122  *  'PWM_count' which is initialized to the number of PWM instances the
123  *  application has defined in the PWM_Config array.
124  *
125  *  You will need to check the device-specific PWM driver implementation's
126  *  header file for example configuration.  Please also refer to the
127  *  Board.c file of any of your examples to see the PWM configuration.
128  *
129  *  ### Initializing the PWM Driver #
130  *
131  *  PWM_init() must be called before any other PWM APIs.  This function
132  *  calls the device implementation's PWM initialization function, for each
133  *  element of PWM_config[].
134  *
135  *  ### Opening the PWM Driver #
136  *
137  *  Opening a PWM requires four steps:
138  *  1.  Create and initialize a PWM_Params structure.
139  *  2.  Fill in the desired parameters.
140  *  3.  Call PWM_open(), passing the index of the PWM in the PWM_config
141  *      structure, and the address of the PWM_Params structure.  The
142  *      PWM instance is specified by the index in the PWM_config structure.
143  *  4.  Check that the PWM handle returned by PWM_open() is non-NULL,
144  *      and save it.  The handle will be used to read and write to the
145  *      PWM you just opened.
146  *
147  *  Only one PWM index can be used at a time; calling PWM_open() a second
148  *  time with the same index previously passed to PWM_open() will result in
149  *  an error.  You can, though, re-use the index if the instance is closed
150  *  via PWM_close().
151  *  In the example code, Board_PWM0 is passed to PWM_open().  This macro
152  *  is defined in the example's Board.h file.
153  *
154  *  ### Modes of Operation #
155  *
156  *  A PWM instance can be configured to interpret the period as one of three
157  *  units:
158  *      - #PWM_PERIOD_US: The period is in microseconds.
159  *      - #PWM_PERIOD_HZ: The period is in (reciprocal) Hertz.
160  *      - #PWM_PERIOD_COUNTS: The period is in timer counts.
161  *
162  *  A PWM instance can be configured to interpret the duty as one of three
163  *  units:
164  *      - #PWM_DUTY_US: The duty is in microseconds.
165  *      - #PWM_DUTY_FRACTION: The duty is in a fractional part of the period
166  *                           where 0 is 0% and #PWM_DUTY_FRACTION_MAX is 100%.
167  *      - #PWM_DUTY_COUNTS: The period is in timer counts and must be less than
168  *                         the period.
169  *
170  *  The idle level parameter is used to set the output to high/low when the
171  *  PWM is not running (stopped or not started).  The idle level can be
172  *  set to:
173  *      - #PWM_IDLE_LOW
174  *      - #PWM_IDLE_HIGH
175  *
176  *  The default PWM configuration is to set a duty of 0% with a 1MHz frequency.
177  *  The default period units are in PWM_PERIOD_HZ and the default duty units
178  *  are in PWM_DUTY_FRACTION.  Finally, the default output idle level is
179  *  PWM_IDLE_LOW.  It is the application's responsibility to set the duty for
180  *  each PWM output used.
181  *
182  *  ### Controlling the PWM Duty Cycle #
183  *
184  *  Once the PWM instance has been opened and started, the primary API used
185  *  by the application will be #PWM_setDuty() to control the duty cycle of a
186  *  PWM pin:
187  *
188  *  @code
189  *     PWM_setDuty(pwm, PWM_DUTY_FRACTION_MAX / 2); // Set 50% duty cycle
190  *  @endcode
191  *
192  *  # Implementation #
193  *
194  *  The PWM driver interface module is joined (at link time) to an
195  *  array of PWM_Config data structures named *PWM_config*.
196  *  PWM_config is implemented in the application with each entry being a
197  *  PWM instance. Each entry in *PWM_config* contains a:
198  *  - (PWM_FxnTable *) to a set of functions that implement a PWM peripheral
199  *  - (void *) data object that is associated with the PWM_FxnTable
200  *  - (void *) hardware attributes that are associated with the PWM_FxnTable
201  *
202  *  The PWM APIs are redirected to the device specific implementations
203  *  using the PWM_FxnTable pointer of the PWM_config entry.
204  *  In order to use device specific functions of the PWM driver directly,
205  *  link in the correct driver library for your device and include the
206  *  device specific PWM driver header file (which in turn includes PWM.h).
207  *  For example, for the MSP432 family of devices, you would include the
208  *  following header file:
209  *    @code
210  *    #include <ti/drivers/pwm/PWMTimerMSP432.h>
211  *    @endcode
212  *
213  *  ============================================================================
214  */
215
216 #ifndef ti_drivers_PWM__include
217 #define ti_drivers_PWM__include
218
219 #ifdef __cplusplus
220 extern "C" {
221 #endif
222
223 #include <stdint.h>
224
225 /*!
226  *  @brief Maximum duty (100%) when configuring duty cycle as a fraction of
227  *  period.
228  */
229 #define PWM_DUTY_FRACTION_MAX        ((uint32_t) ~0)
230
231 /*!
232  * Common PWM_control command code reservation offset.
233  * PWM driver implementations should offset command codes with PWM_CMD_RESERVED
234  * growing positively.
235  *
236  * Example implementation specific command codes:
237  * @code
238  * #define PWMXYZ_COMMAND0         (PWM_CMD_RESERVED + 0)
239  * #define PWMXYZ_COMMAND1         (PWM_CMD_RESERVED + 1)
240  * @endcode
241  */
242 #define PWM_CMD_RESERVED             (32)
243
244 /*!
245  * Common PWM_control status code reservation offset.
246  * PWM driver implementations should offset status codes with
247  * PWM_STATUS_RESERVED growing negatively.
248  *
249  * Example implementation specific status codes:
250  * @code
251  * #define PWMXYZ_STATUS_ERROR0    (PWM_STATUS_RESERVED - 0)
252  * #define PWMXYZ_STATUS_ERROR1    (PWM_STATUS_RESERVED - 1)
253  * #define PWMXYZ_STATUS_ERROR2    (PWM_STATUS_RESERVED - 2)
254  * @endcode
255  */
256 #define PWM_STATUS_RESERVED          (-32)
257
258 /*!
259  * @brief  Success status code returned by:
260  * PWM_control(), PWM_setDuty(), PWM_setPeriod().
261  *
262  * Functions return PWM_STATUS_SUCCESS if the call was executed
263  * successfully.
264  */
265 #define PWM_STATUS_SUCCESS           (0)
266
267 /*!
268  * @brief   Generic error status code returned by PWM_control().
269  *
270  * PWM_control() returns PWM_STATUS_ERROR if the control code was not executed
271  * successfully.
272  */
273 #define PWM_STATUS_ERROR             (-1)
274
275 /*!
276  * @brief   An error status code returned by PWM_control() for undefined
277  * command codes.
278  *
279  * PWM_control() returns PWM_STATUS_UNDEFINEDCMD if the control code is not
280  * recognized by the driver implementation.
281  */
282 #define PWM_STATUS_UNDEFINEDCMD      (-2)
283
284 /*!
285  * @brief   An error status code returned by PWM_setPeriod().
286  *
287  * PWM_setPeriod() returns PWM_STATUS_INVALID_PERIOD if the period argument is
288  * invalid for the current configuration.
289  */
290 #define PWM_STATUS_INVALID_PERIOD    (-3)
291
292 /*!
293  * @brief   An error status code returned by PWM_setDuty().
294  *
295  * PWM_setDuty() returns PWM_STATUS_INVALID_DUTY if the duty cycle argument is
296  * invalid for the current configuration.
297  */
298 #define PWM_STATUS_INVALID_DUTY      (-4)
299
300 /*!
301  *  @brief   PWM period unit definitions.  Refer to device specific
302  *  implementation if using PWM_PERIOD_COUNTS (raw PWM/Timer counts).
303  */
304 typedef enum PWM_Period_Units_ {
305     PWM_PERIOD_US,    /* Period in microseconds */
306     PWM_PERIOD_HZ,    /* Period in (reciprocal) Hertz
307                          (for example 2MHz = 0.5us period) */
308     PWM_PERIOD_COUNTS /* Period in timer counts */
309 } PWM_Period_Units;
310
311 /*!
312  *  @brief   PWM duty cycle unit definitions.  Refer to device specific
313  *  implementation if using PWM_DUTY_COUNTS (raw PWM/Timer counts).
314  */
315 typedef enum PWM_Duty_Units_ {
316     PWM_DUTY_US,       /* Duty cycle in microseconds */
317     PWM_DUTY_FRACTION, /* Duty as a fractional part of PWM_DUTY_FRACTION_MAX */
318     PWM_DUTY_COUNTS    /* Duty in timer counts  */
319 } PWM_Duty_Units;
320
321 /*!
322  *  @brief   Idle output level when PWM is not running (stopped / not started).
323  */
324 typedef enum PWM_IdleLevel_ {
325     PWM_IDLE_LOW  = 0,
326     PWM_IDLE_HIGH = 1,
327 } PWM_IdleLevel;
328
329 /*!
330  *  @brief PWM Parameters
331  *
332  *  PWM Parameters are used to with the PWM_open() call. Default values for
333  *  these parameters are set using PWM_Params_init().
334  *
335  *  @sa     PWM_Params_init()
336  */
337 typedef struct PWM_Params_ {
338     PWM_Period_Units periodUnits; /*!< Units in which the period is specified */
339     uint32_t         periodValue; /*!< PWM initial period */
340     PWM_Duty_Units   dutyUnits;   /*!< Units in which the duty is specified */
341     uint32_t         dutyValue;   /*!< PWM initial duty */
342     PWM_IdleLevel    idleLevel;   /*!< Pin output when PWM is stopped. */
343     void            *custom;      /*!< Custom argument used by driver
344                                        implementation */
345 } PWM_Params;
346
347 /*!
348  *  @brief      A handle that is returned from a PWM_open() call.
349  */
350 typedef struct PWM_Config_ *PWM_Handle;
351
352 /*!
353  *  @brief      A function pointer to a driver specific implementation of
354  *              PWM_close().
355  */
356 typedef void (*PWM_CloseFxn) (PWM_Handle handle);
357
358 /*!
359  *  @brief      A function pointer to a driver specific implementation of
360  *              PWM_control().
361  */
362 typedef int_fast16_t (*PWM_ControlFxn) (PWM_Handle handle, uint_fast16_t cmd,
363     void *arg);
364 /*!
365  *  @brief      A function pointer to a driver specific implementation of
366  *              PWM_init().
367  */
368 typedef void (*PWM_InitFxn) (PWM_Handle handle);
369
370 /*!
371  *  @brief      A function pointer to a driver specific implementation of
372  *              PWM_open().
373  */
374 typedef PWM_Handle (*PWM_OpenFxn) (PWM_Handle handle, PWM_Params *params);
375
376 /*!
377  *  @brief      A function pointer to a driver specific implementation of
378  *              PWM_setDuty().
379  */
380 typedef int_fast16_t (*PWM_SetDutyFxn) (PWM_Handle handle,
381     uint32_t duty);
382
383 /*!
384  *  @brief      A function pointer to a driver specific implementation of
385  *              PWM_setPeriod().
386  */
387 typedef int_fast16_t (*PWM_SetPeriodFxn) (PWM_Handle handle,
388     uint32_t period);
389
390 /*!
391  *  @brief      A function pointer to a driver specific implementation of
392  *              PWM_start().
393  */
394 typedef void (*PWM_StartFxn) (PWM_Handle handle);
395
396 /*!
397  *  @brief      A function pointer to a driver specific implementation of
398  *              PWM_stop().
399  */
400 typedef void (*PWM_StopFxn) (PWM_Handle handle);
401
402 /*!
403  *  @brief      The definition of a PWM function table that contains the
404  *              required set of functions to control a specific PWM driver
405  *              implementation.
406  */
407 typedef struct PWM_FxnTable_ {
408     /*! Function to close the specified instance */
409     PWM_CloseFxn     closeFxn;
410     /*! Function to driver implementation specific control function */
411     PWM_ControlFxn   controlFxn;
412     /*! Function to initialize the given data object */
413     PWM_InitFxn      initFxn;
414     /*! Function to open the specified instance */
415     PWM_OpenFxn      openFxn;
416     /*! Function to set the duty cycle for a specific instance */
417     PWM_SetDutyFxn   setDutyFxn;
418     /*! Function to set the period for a specific instance */
419     PWM_SetPeriodFxn setPeriodFxn;
420     /*! Function to start the PWM output for a specific instance */
421     PWM_StartFxn     startFxn;
422     /*! Function to stop the PWM output for a specific instance */
423     PWM_StopFxn      stopFxn;
424 } PWM_FxnTable;
425
426 /*!
427  *  @brief  PWM Global configuration.
428  *
429  *  The PWM_Config structure contains a set of pointers used to characterize
430  *  the PWM driver implementation.
431  *
432  */
433 typedef struct PWM_Config_ {
434     /*! Pointer to a table of driver-specific implementations of PWM APIs */
435     PWM_FxnTable const *fxnTablePtr;
436     /*! Pointer to a driver specific data object */
437     void               *object;
438     /*! Pointer to a driver specific hardware attributes structure */
439     void         const *hwAttrs;
440 } PWM_Config;
441
442 /*!
443  *  @brief  Function to close a PWM instance specified by the PWM handle.
444  *
445  *  @pre    PWM_open() must have been called first.
446  *  @pre    PWM_stop() must have been called first if PWM was started.
447  *
448  *  @param  handle A PWM handle returned from PWM_open().
449  *
450  *  @sa     PWM_open()
451  *  @sa     PWM_start()
452  *  @sa     PWM_stop()
453  */
454 extern void PWM_close(PWM_Handle handle);
455
456 /*!
457  *  @brief  Function performs implementation specific features on a given
458  *          PWM_Handle.
459  *
460  *  @pre    PWM_open() must have been called first.
461  *
462  *  @param  handle      A PWM handle returned from PWM_open().
463  *
464  *  @param  cmd         A command value defined by the driver specific
465  *                      implementation.
466  *
467  *  @param  arg         A pointer to an optional R/W (read/write) argument that
468  *                      is accompanied with cmd.
469  *
470  *  @return A PWM_Status describing an error or success state. Negative values
471  *          indicate an error occurred.
472  *
473  *  @sa     PWM_open()
474  */
475 extern int_fast16_t PWM_control(PWM_Handle handle, uint_fast16_t cmd,
476     void *arg);
477
478 /*!
479  *  @brief  This function initializes the PWM module.
480  *
481  *  @pre    The PWM_config structure must exist and be persistent before this
482  *          function can be called. This function must be called before any
483  *          other PWM driver APIs.  This function does not modify any peripheral
484  *          registers & should only be called once.
485  */
486 extern void PWM_init(void);
487
488 /*!
489  *  @brief  This function opens a given PWM instance and sets the period,
490  *          duty and idle level to those specified in the params argument.
491  *
492  *  @param  index         Logical instance number for the PWM indexed into
493  *                        the PWM_config table.
494  *
495  *  @param  params        Pointer to an parameter structure.  If NULL default
496  *                        values are used.
497  *
498  *  @return A PWM_Handle if successful or NULL on an error or if it has been
499  *          opened already. If NULL is returned further PWM API calls will
500  *          result in undefined behavior.
501  *
502  *  @sa     PWM_close()
503  */
504 extern PWM_Handle PWM_open(uint_least8_t index, PWM_Params *params);
505
506 /*!
507  *  @brief  Function to initialize the PWM_Params structure to default values.
508  *
509  *  @param  params      A pointer to PWM_Params structure for initialization.
510  *
511  *  Defaults values are:
512  *      Period units: PWM_PERIOD_HZ
513  *      Period: 1e6  (1MHz)
514  *      Duty cycle units: PWM_DUTY_FRACTION
515  *      Duty cycle: 0%
516  *      Idle level: PWM_IDLE_LOW
517  */
518 extern void PWM_Params_init(PWM_Params *params);
519
520 /*!
521  *  @brief  Function to set the duty cycle of the specified PWM handle.  PWM
522  *          instances run in active high output mode; 0% is always low output,
523  *          100% is always high output.  This API can be called while the PWM
524  *          is running & duty must always be lower than or equal to the period.
525  *          If an error occurs while calling the function the PWM duty cycle
526  *          will remain unchanged.
527  *
528  *  @pre    PWM_open() must have been called first.
529  *
530  *  @param  handle      A PWM handle returned from PWM_open().
531  *
532  *  @param  duty        Duty cycle in the units specified by the params used
533  *                      in PWM_open().
534  *
535  *  @return A PWM status describing an error or success. Negative values
536  *          indicate an error.
537  *
538  *  @sa     PWM_open()
539  */
540 extern int_fast16_t PWM_setDuty(PWM_Handle handle, uint32_t duty);
541
542 /*!
543  *  @brief  Function to set the period of the specified PWM handle. This API
544  *          can be called while the PWM is running & the period must always be
545  *          larger than the duty cycle.
546  *          If an error occurs while calling the function the PWM period
547  *          will remain unchanged.
548  *
549  *  @pre    PWM_open() must have been called first.
550  *
551  *  @param  handle      A PWM handle returned from PWM_open().
552  *
553  *  @param  period      Period in the units specified by the params used
554  *                      in PWM_open().
555  *
556  *  @return A PWM status describing an error or success state. Negative values
557  *          indicate an error.
558  *
559  *  @sa     PWM_open()
560  */
561 extern int_fast16_t PWM_setPeriod(PWM_Handle handle, uint32_t period);
562
563 /*!
564  *  @brief  Function to start the specified PWM handle with current settings.
565  *
566  *  @pre    PWM_open() has to have been called first.
567  *
568  *  @param  handle      A PWM handle returned from PWM_open().
569  *
570  *  @sa     PWM_open()
571  *  @sa     PWM_stop()
572  */
573 extern void PWM_start(PWM_Handle handle);
574
575 /*!
576  *  @brief  Function to stop the specified PWM handle. Output will set to the
577  *          idle level specified by params in PWM_open().
578  *
579  *  @pre    PWM_open() has to have been called first.
580  *
581  *  @param  handle      A PWM handle returned from PWM_open().
582  *
583  *  @sa     PWM_open()
584  *  @sa     PWM_start()
585  */
586 extern void PWM_stop(PWM_Handle handle);
587
588 #ifdef __cplusplus
589 }
590 #endif
591 #endif /* ti_drivers_PWM__include */