PIN.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2021, 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 /*!*****************************************************************************
34  * @file PIN.h
35  * @brief Generic PIN & GPIO driver
36  *
37  *
38  * @warning The PIN driver will be removed in the 2Q22 release. Please port your
39  * application to the updated GPIO driver, which has been updated and is now at
40  * feature parity but is simpler to use, operates faster and requires less
41  * memory.
42  *
43  * To use the PIN driver ensure that the correct TI-RTOS driver library for your
44  * device is linked in and include this header file:
45  * @code
46  * #include <ti/drivers/PIN.h>
47  * @endcode
48  *
49  * In order to use device-specific functionality or to use the size/speed-
50  * optimized versions of some of the PIN driver functions that circumvent error
51  * and resource checking, link in the correct TI-RTOS driver library for your
52  * device and include the device-specific PIN driver header file (which in turn
53  * includes PIN.h). As an example for the CC26xx family of devices:
54  * @code
55  * #include <ti/drivers/pin/PINCC26xx.h>
56  * @endcode
57  *
58  * # Overview #
59  * The PIN driver allows clients (applications or other drivers) to allocate
60  * and control the I/O pins on the device. The pins can either be software-
61  * controlled general-purpose I/O (GPIO) or connected to hardware peripherals.
62  * Furthermore, the PIN driver allows clients to configure interrupt
63  * functionality on the pins to receive callbacks (and potentially wake up from
64  * the standby or idle power modes) on configurable signal edges.
65  *
66  * Most other drivers rely on functionality in the PIN driver.
67  *
68  * ## Structure ##
69  * In order to provide a generic driver interface, this file (PIN.h) only
70  * defines the API and some common data types and macros of the driver. A PIN
71  * client (application or driver) can in most cases only use the generic PIN
72  * API, however, for more advanced usage where device-specific pin
73  * configuration is used or device-specific PIN driver API extensions are
74  * used must use the device-specific PIN driver API.
75  *
76  * The device-independent API is implemented as function calls with pin
77  * access control based on the PIN client handle. For time-critical
78  * applications the device-specific API can be used directly, as these
79  * API functions are implemented as inlined functions without access control.
80  *
81  * ## Functionality ##
82  * The PIN module provides the following functionality:
83  * - Initialize I/O pins upon boot to a default configuration (possibly
84  * user-generated)
85  * - Provides atomic manipulation of I/O pin hardware registers to allow safe
86  * simultaneous use of I/O pin resources
87  * - I/O pin allocation
88  * - A set of pins can be allocated receiving a pin set handle.
89  * Typically each peripheral driver will allocate a set of pins and an
90  * application must allocate the pins it uses too
91  * - When a pin set is deallocated all the pins in it revert to the state
92  * they were initialized to at boot
93  * - General-purpose I/O (GPIO) services
94  * - Read input buffer value
95  * - Read and set output buffer value
96  * - Read and set output buffer enable
97  * - Access as single pin or port (muliple pins simultaneously)
98  * - Protect pin manipulation
99  * - Pins in an allocated set can only be manipulated using the corresponding
100  * handle.
101  * - No handle is needed to read input and output buffer values
102  * - I/O buffer/driver control
103  * - Input mode (detached, hysteresis, pull-up, pull-down)
104  * - Output mode (tristated, push-pull, open drain, open source)
105  * - Output driver strength control
106  * - Output driver slew rate control
107  * - I/O source/target selection (device-specific driver only)
108  * - Map pin to GPIO, peripheral or HW observation signal
109  * - Configuration of I/O interrupt and wakeup from standby
110  * - Interrupt configuration: signal edge to interrupt on, interrupt mask,
111  * callback function registration
112  * - Pins that have enabled interrupts will also wake up the device from low-
113  * power modes like standby and idle upon events
114  * - Provides data types and enums/defines for use in pin configurations
115  * definitions in board files, drivers and applications
116  *
117  * ## Pin Allocation ##
118  * The purpose of being able to allocate pins to a pin set is to:
119  * - Manage pin resources
120  * - Give exclusive, protected access to these pins
121  * - Establish a driver state in connection with these pins that allow
122  * functionality such as I/O interrupt callback and I/O port operations
123  * in a safe manner
124  *
125  * | API function | Description |
126  * |--------------------|------------------------------------------------------|
127  * | PIN_open() | Allocate pins to a set, returns handle |
128  * | PIN_add() | Add pin to pin set for open PIN handle |
129  * | PIN_remove() | Removes pin from pin set for open PIN handle |
130  * | PIN_close() | Deallocate pin set, revert to original GPIO state |
131  *
132  * ## GPIO ##
133  * Pins that are to be used as software-controlled general-purpose I/O (GPIO)
134  * need to be allocated in the same manner as for pins that will be mapped to
135  * hardware peripheral ports. A pin set requested with a PIN_open() call may
136  * contain a mix of pins to be used for GPIO and hardware-mapped pins.
137  *
138  * When a pin is deallocated using PIN_close() it reverts to the GPIO
139  * configuration it was given in the initial call to PIN_init().
140  *
141  * | API function | Description |
142  * |----------------------|---------------------------------------------------|
143  * | PIN_init() | Initialize I/O pins to a safe GPIO state |
144  * | PIN_open() | Allocate pins to a set, returns handle |
145  * | PIN_close() | Deallocate pin set, revert to original GPIO state |
146  * | PIN_setConfig() | Sets parts of or complete pin configuration |
147  * | PIN_getConfig() | Returns pin configuration |
148  * | PIN_setOutputEnable()| Control output enable of GPIO pin |
149  * | PIN_getInputValue() | Read input value on pin |
150  * | PIN_setOutputValue() | Set output value of GPIO pin |
151  * | PIN_getOutputValue() | Get current output value of GPIO pin |
152  *
153  * ## GPIO Ports ##
154  * Sometimes it is necessary to be able to read from, write to or control
155  * multiple pins simultaneously (in time). The PIN driver allows a set of
156  * allocated pins, if they reside on the same GPIO port in the underlying
157  * hardware, to be manipulated simultaneously.
158  *
159  * | API function | Description |
160  * |--------------------------|---------------------------------------------------|
161  * | PIN_open() | Allocate pins to a set, returns handle |
162  * | PIN_close() | Deallocate pin set, revert to original GPIO state |
163  * | PIN_getPortMask() | Returns bitmask for allocated pins in GPIO port |
164  * | PIN_getPortInputValue() | Returns input value of whole GPIO port |
165  * | PIN_setPortOutputValue() | Sets output value of whole GPIO port (masked) |
166  * | PIN_getPortOutputValue() | Get current output value of whole GPIO port |
167  * | PIN_setPortOutputValue() | Sets output value of whole GPIO port (masked) |
168  * | PIN_setPortOutputEnable()| Sets output enable of whole GPIO port (masked) |
169  *
170  * ## I/O Pin Configuration ##
171  * Different devices provide different levels of configurability of I/O pins.
172  * The PIN driver provides a fairly extensive set of @ref PIN_GENERIC_FLAGS
173  * "generic IO configuration options" that are device-independent, all of which
174  * might not be supported by the underlying device-specific PIN driver and
175  * hardware. Likewise, the underlying device-specific PIN driver and hardware
176  * might support additional configuration options not covered by the generic
177  * options.
178  *
179  * To allow both independence from and flexibility to use features on the target
180  * device, the #PIN_Config entries used by the PIN driver allows use of either
181  * a set of @ref PIN_GENERIC_FLAGS "generic PIN configuration options" or a
182  * device-specific set of PIN configuration options defined in the underlying
183  * device-specific PIN driver (e.g. PINCC26XX.h)
184  *
185  * ### Mapping to GPIO or Peripheral ###
186  * Since the amount of flexibilty in which peripherals can be mapped to which
187  * pins and the manner in which this needs to be set up is highly
188  * device-specific, functions for configuring this is not part of the generic
189  * PIN driver API but is left to be implemented by device-specific PIN drivers.
190  * See the relevant device-specific PIN driver (e.g. PINCC26XX.h) for details.
191  *
192  * ### Input Mode ###
193  * The input mode of a pin controls:
194  * - Input buffer enable
195  * - Pull-ups or pull-downs
196  * - Hysteresis of input buffer
197  * - Inversion of logical input level
198  * - Potentially, device-specific options
199  * The input mode is set initially with PIN_init() or at a later stage with
200  * PIN_setConfig() and a bitmask with the relevant options
201  *
202  * | API function | Description |
203  * |------------------|-------------------------------------------------------|
204  * | PIN_init() | Initialize IOs to a safe GPIO state |
205  * | PIN_getConfig() | Returns pin configuration |
206  * | PIN_setConfig() | Sets parts of or complete pin configuration |
207  *
208  * ### Output Mode ###
209  * The output mode of a pin controls:
210  * - Output buffer enable
211  * - Output driver mode (push-pull, open-drain, open-source)
212  * - Output driver slew control
213  * - Output driver current (drive strength)
214  * - Inversion of logical output level
215  * - Potentially, device-specific options
216  *
217  * | API function | Description |
218  * |----------------------|---------------------------------------------------|
219  * | PIN_init() | Initialize IOs to a safe GPIO state |
220  * | PIN_setOutputEnable()| Control output enable of GPIO pins |
221  * | PIN_getConfig() | Returns pin configuration |
222  * | PIN_setConfig() | Sets parts of or complete pin configuration |
223  *
224  * ### Pin Interrupt and Pin Wakeup ###
225  * Pin interrupts are used to process asynchronous signal edge events on pins
226  * and potentially wake the device up from low power sleep modes. To use pin
227  * interrupts the relevant pins must be allocated and a interrupt callback
228  * registered by the client. The callback function will be called in a SWI
229  * context.
230  *
231  * | API function | Description |
232  * |---------------------|----------------------------------------------------|
233  * | PIN_init() | Initialize IOs to a safe GPIO state |
234  * | PIN_getConfig() | Returns pin configuration |
235  * | PIN_setConfig() | Sets parts of or complete pin configuration |
236  * | PIN_setInterrupt() | Control interrupt enable and edge for pin |
237  * | PIN_registerIntCb() | Register callback function for a set of pins |
238  * | PIN_setUserArg() | Sets a user argument associated with the handle |
239  * | PIN_getUserArg() | Gets a user argument associated with the handle |
240  *
241  * ## PIN Data Types ##
242  * The PIN driver defines the following data types:
243  * - #PIN_Id: identifies a pin in arguments or lists
244  * - #PIN_Config: provides I/O configuration options for a pin and also embeds
245  * a #PIN_Id identifier. See @ref PIN_GENERIC_FLAGS "available flags/fields"
246  *
247  * ## PIN Config Flags/Fields and Bitmasks ##
248  * The PIN driver uses the #PIN_Config data type many places and it merits some
249  * additional attention. A #PIN_Config value consists of a collection of flags
250  * and fields that define how an I/O pin and its attached GPIO interface should
251  * behave electrically and logically. In addition a #PIN_Config value also
252  * embeds a #PIN_Id pin ID, identifying which pin it refers to.
253  *
254  * A #PIN_Config value can use one of two mutually exclusive sets of flags and
255  * fields: @ref PIN_GENERIC_FLAGS "device-independent options" defined in
256  * PIN.h or device-dependent options defined in the device-specific
257  * implementation of the PIN driver interface. Any function that uses
258  * #PIN_Config will accept both option types, just not at the same time.
259  * PIN_getConfig() always returns device-independent options, an additional
260  * device-specific version (e.g. PINCC26XX_getConfig()) might return
261  * device-specific options.
262  *
263  * The bitmask argument for PIN_setConfig() decides which of the options the
264  * call should affect. All other options are kept at their current values in
265  * hardware. Thus PIN_setConfig(hPins, PIN_BM_PULLING, PIN_BM_PULLUP) will only
266  * change the pullup/pulldown configuration of the pin, leaving everything
267  * else, such as for instance output enable, input hysteresis or output value,
268  * untouched. For #PIN_Config lists (as supplied to PIN_init() for instance)
269  * there is no mask, so all options will affect the pin.
270  *
271  * Some of the options affect the pin regardless of whether it is mapped to
272  * a hardware peripheral or GPIO and some options only take effect when it is
273  * mapped to GPIO. These latter options have \_GPIO_ in their names.
274  *
275  * The default value for a flag/field is indicated with a star (*) in the
276  * description of the options and will be applied if any explicit value is
277  * not supplied for a flag/field that is masked.
278  *
279  * The available options can be grouped into categories as follows:
280  *
281  * ### Input Mode Options ###
282  * | Option | Option bitmask | HW/GPIO | Description |
283  * |--------------------|-----------------------|---------|--------------------------------|
284  * |#PIN_INPUT_EN (*) |#PIN_BM_INPUT_EN | Both | Enable pin input buffer |
285  * |#PIN_INPUT_DIS |#PIN_BM_INPUT_EN | Both | Disable pin input buffer |
286  * |#PIN_HYSTERESIS |#PIN_BM_HYSTERESIS | Both | Enable hysteresis on input |
287  * |#PIN_NOPULL (*) |#PIN_BM_PULLING | Both | No pullup/pulldown |
288  * |#PIN_PULLUP |#PIN_BM_PULLING | Both | Enable pullup |
289  * |#PIN_PULLDOWN |#PIN_BM_PULLING | Both | Enable pulldown |
290  * | |#PIN_BM_INPUT_MODE | | Mask for all input mode options|
291  *
292  * ### Output Mode Options ###
293  * | Option | Option bitmask | HW/GPIO | Description |
294  * |------------------------|------------------------|---------|----------------------------------|
295  * |#PIN_GPIO_OUTPUT_DIS (*)|#PIN_BM_GPIO_OUTPUT_EN | GPIO | Disable GPIO output buffer |
296  * |#PIN_GPIO_OUTPUT_EN |#PIN_BM_GPIO_OUTPUT_EN | GPIO | Enable GPIO output buffer |
297  * |#PIN_GPIO_LOW (*) |#PIN_BM_GPIO_OUTPUT_VAL | GPIO | Output 0 when GPIO |
298  * |#PIN_GPIO_HIGH |#PIN_BM_GPIO_OUTPUT_VAL | GPIO | Output 1 when GPIO |
299  * |#PIN_PUSHPULL (*) |#PIN_BM_OUTPUT_BUF | Both | Use push-pull output buffer |
300  * |#PIN_OPENDRAIN |#PIN_BM_OUTPUT_BUF | Both | Use open drain output buffer |
301  * |#PIN_OPENSOURCE |#PIN_BM_OUTPUT_BUF | Both | Use open source output buffer |
302  * |#PIN_SLEWCTRL |#PIN_BM_SLEWCTRL | Both | Enable output buffer slew control|
303  * |#PIN_DRVSTR_MIN (*) |#PIN_BM_DRVSTR | Both | Output buffer uses min drive |
304  * |#PIN_DRVSTR_MED |#PIN_BM_DRVSTR | Both | Output buffer uses medium drive |
305  * |#PIN_DRVSTR_MAX |#PIN_BM_DRVSTR | Both | Output buffer uses max drive |
306  * | |#PIN_BM_OUTPUT_MODE | | Mask for all output mode options |
307  *
308  * ### Misc Options ###
309  * | Option | Option bitmask | HW/GPIO | Description |
310  * |-------------------|------------------|---------|----------------------------------|
311  * |#PIN_INV_INOUT |#PIN_BM_INV_INOUT | Both | Invert input/output |
312  * |#PIN_IRQ_DIS (*) |#PIN_BM_IRQ | Both | Disable pin interrupts |
313  * |#PIN_IRQ_NEGEDGE |#PIN_BM_IRQ | Both | Pin interrupts on negative edges |
314  * |#PIN_IRQ_POSEDGE |#PIN_BM_IRQ | Both | Pin interrupts on positive edges |
315  * |#PIN_IRQ_BOTHEDGES |#PIN_BM_IRQ | Both | Pin interrupts on both edges |
316  * | |#PIN_BM_ALL | | Mask for *all* options |
317  *
318  * ## Initialization ##
319  * The PIN driver must be initialized before any other drivers are initialized.
320  * In order for IO pins to get a safe value as soon as possible PIN_init()
321  * should be called as early as possible in the boot sequence. Typically,
322  * PIN_init() is called at the start of main() before TI-RTOS is started with
323  * BIOS_start().
324  *
325  * PIN_init() takes as an argument a #PIN_Config list containing default pin
326  * configurations. Typically the #PIN_Config list defined in the board files
327  * is used:
328  * @code
329  * PIN_init(BoardGpioInitTable);
330  * @endcode
331  * It is possible, however, to use another #PIN_Config list if desired.
332  *
333  * ## Power Management Interaction ##
334  * No specific interaction with power management module, as PIN is independent
335  * of power mode.
336  *
337  * ## Functionality Not Supported ##
338  * There is no known unsupported functionality.
339  *
340  * ## Instrumentation ##
341  * The pin driver does not use any of the instrumentation facilities.
342  *
343  * # Usage Examples #
344  *
345  * ## Initialization and Pin Allocation ##
346  * Example that illustrates when and how to call PIN_init(), PIN_open(), PIN_add(), PIN_close()
347  * @code
348  * // Default pin configuration. Typically resides in ti_drivers_config.c file.
349  * // IOs not mentioned here configured to default: input/output/pull disabled
350  * PIN_Config BoardGpioInitTable[] = {
351  * // DIO11: LED A (initially off)
352  * PIN_ID(11) | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
353  * // DIO10: LED B (initially off)
354  * PIN_ID(10) | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
355  * // DIO23: BUTTON A (ensure pull-up as button A is also used by other ICs)
356  * PIN_ID(23) | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,
357  * // DIO3: LCD controller reset line (make sure LCD is in reset)
358  * PIN_ID(3) | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
359  * // Terminate list
360  * PIN_TERMINATE
361  * };
362  *
363  * //Stack size in bytes
364  * #define THREADSTACKSIZE 1024
365  *
366  * // PIN_init() should be called as early as possible in boot
367  * void main() {
368  *
369  * pthread_t thread;
370  * pthread_attr_t attrs;
371  * struct sched_param priParam;
372  * int retc;
373  * int detachState;
374  *
375  * //Board_init() will call PIN_init(BoardGpioInitTable)
376  * Board_init();
377  *
378  * // Set priority and stack size attributes
379  * pthread_attr_init(&attrs);
380  * priParam.sched_priority = 1;
381  *
382  * detachState = PTHREAD_CREATE_DETACHED;
383  * retc = pthread_attr_setdetachstate(&attrs, detachState);
384  * if (retc != 0) {
385  * // pthread_attr_setdetachstate() failed
386  * while (1);
387  * }
388  *
389  * pthread_attr_setschedparam(&attrs, &priParam);
390  *
391  * retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
392  * if (retc != 0) {
393  * // pthread_attr_setstacksize() failed
394  * while (1);
395  * }
396  *
397  * retc = pthread_create(&thread, &attrs, mainThread, NULL);
398  * if (retc != 0) {
399  * // pthread_create() failed
400  * while (1);
401  * }
402  *
403  * // Start kernel
404  * Add_Kernel_Start_Call();
405  *
406  * return (0);
407  * }
408  *
409  * // Human user interface PIN state/handle
410  * PIN_State hStateHui;
411  * #define HUI_LED_A PIN_ID(11)
412  * #define HUI_LED_B PIN_ID(10)
413  * #define HUI_LED_C PIN_ID(9)
414  * #define HUI_BUTTON_A PIN_ID(23)
415  * #define HUI_BUTTON_B PIN_ID(24)
416  *
417  * static void taskStartFxn(UArg a0, UArg a1) {
418  * // Define pins used by Human user interface and initial configuration
419  * const PIN_Config pinListHui[] = {
420  * HUI_LED_A | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
421  * HUI_LED_B | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
422  * HUI_BUTTON_A | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,
423  * HUI_BUTTON_B | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,
424  * PIN_TERMINATE
425  * };
426  *
427  * // Get handle to this collection of pins
428  * if (!PIN_open(&hStateHui, pinListHui)) {
429  * // Handle allocation error
430  * }
431  *
432  * // ...
433  *
434  * // We can also add (and remove) pins to a set at run time
435  * PIN_Status status = PIN_add(
436  * &hStateHui,
437  * HUI_LED_C | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
438  * );
439  * if (status != PIN_SUCCESS) {
440  * // Handling allocation error is especially important with PIN_add()
441  * }
442  *
443  * // ...
444  * huiDoSomething();
445  *
446  * // Before ending task, make sure to deallocate pins. They will return
447  * // to the default configurations provided in PIN_init()
448  * PIN_close(&hStateHui);
449  * }
450  * @endcode
451  *
452  * ## Application use of GPIO ##
453  * An example of using GPIO that builds on the previous example. Illustrates how
454  * to read input values, set output values and control output enable
455  * @code
456  * void huiDoSomething() {
457  * // Running lights on LEDs A-B-C (left to right). Button A causes left
458  * // movement, button B causes right movement, both simultaneously aborts
459  * // and disables LED output drivers
460  *
461  * // LED initial state (A off, B off, C on). Only our outputs are affected
462  * PIN_setPortOutputValue(&hStateHui, (1<<HUI_LED_C));
463  *
464  * int32_t moveDir = -1; // <0: left, 0: stop, >0 right
465  * while (moveDir) {
466  * // Update LEDs
467  * if (moveDir<0) {
468  * // Left movement
469  * uint32_t t = PIN_getOutputValue(HUI_LED_A);
470  * PIN_setOutputValue(&hStateHui, HUI_LED_A, PIN_getOutputValue(HUI_LED_B));
471  * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_C));
472  * PIN_setOutputValue(&hStateHui, HUI_LED_C, t);
473  * } else {
474  * // Right movement
475  * uint32_t t = PIN_getOutputValue(HUI_LED_C);
476  * PIN_setOutputValue(&hStateHui, HUI_LED_C, PIN_getOutputValue(HUI_LED_B));
477  * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_A));
478  * PIN_setOutputValue(&hStateHui, HUI_LED_A, t);
479  * }
480  *
481  * // Sleep for 333 ms
482  * Task_sleep(333000/10);
483  *
484  * // Read input from both buttons simultaneously
485  * uint32_t buttons = PIN_getPortInputValue(&hStateHui);
486  * if (buttons&(1<<HUI_BUTTON_A) == 0) {
487  * moveDir = -1;
488  * } else if (buttons&(1<<HUI_BUTTON_A) == 0) {
489  * moveDir = 1;
490  * } else if (buttons&((1<<HUI_BUTTON_A)|(1<<HUI_BUTTON_A))) {
491  * moveDir = 0;
492  * }
493  * }
494  * // Disable output enable for all pins (only our pins affected)
495  * PIN_setPortOutputEnable(&hStateHui, 0);
496  * }
497  * @endcode
498  *
499  * ## Pin Interrupt ##
500  * An example that handles pin inputs in the GPIO example above using PIN interrupts
501  * instead:
502  * @code
503  * // volatile variable used to communicate between callback and task
504  * static volatile int32_t moveDir = -1; // <0: left, 0: stop, >0 right
505  *
506  * // Pin interrupt callback
507  * void huiPinIntCb(PIN_Handle handle, PIN_Id pinId) {
508  * // Ignore pinId and read input from both buttons simultaneously
509  * uint32_t buttons = PIN_getPortInputValue(&hStateHui);
510  * if (buttons&(1<<HUI_BUTTON_A) == 0) {
511  * moveDir = -1;
512  * } else if (buttons&(1<<HUI_BUTTON_A) == 0) {
513  * moveDir = 1;
514  * } else if (buttons&((1<<HUI_BUTTON_A)|(1<<HUI_BUTTON_A))) {
515  * moveDir = 0;
516  * }
517  * }
518  *
519  * void huiDoSomething() {
520  * // Running lights on LEDs A-B-C (left to right). Button A causes left
521  * // movement, button B causes right movement, both simultaneously aborts
522  * // and disables LED output drivers
523  *
524  * // LED initial state (A off, B off, C on). Only our outputs are affected
525  * PIN_setPortOutputValue(&hStateHui, (1<<HUI_LED_C));
526  * moveDir = -1; // <0: left, 0: stop, >0 right
527  *
528  * // Setup pin interrupts and register callback
529  * PIN_registerIntCb(&hStateHui, huiPinIntCb);
530  * PIN_setInterrupt(&hStateHui, HUI_BUTTON_A | PIN_IRQ_NEGEDGE);
531  * PIN_setInterrupt(&hStateHui, HUI_BUTTON_B | PIN_IRQ_NEGEDGE);
532  *
533  * while (moveDir) {
534  * // Update LEDs
535  * if (moveDir<0) {
536  * // Left movement
537  * uint32_t t = PIN_getOutputValue(HUI_LED_A);
538  * PIN_setOutputValue(&hStateHui, HUI_LED_A, PIN_getOutputValue(HUI_LED_B));
539  * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_C));
540  * PIN_setOutputValue(&hStateHui, HUI_LED_C, t);
541  * } else {
542  * // Right movement
543  * uint32_t t = PIN_getOutputValue(HUI_LED_C);
544  * PIN_setOutputValue(&hStateHui, HUI_LED_C, PIN_getOutputValue(HUI_LED_B));
545  * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_A));
546  * PIN_setOutputValue(&hStateHui, HUI_LED_A, t);
547  * }
548  *
549  * // Sleep for 333 ms (we will likely go into standby)
550  * Task_sleep(333000/10);
551  * }
552  * // Disable output enable for all pins (only our pins affected)
553  * PIN_setPortOutputEnable(&hStateHui, 0);
554  * // Disable pin interrupts
555  * PIN_setInterrupt(&hStateHui, HUI_BUTTON_A | PIN_IRQ_DIS);
556  * PIN_setInterrupt(&hStateHui, HUI_BUTTON_B | PIN_IRQ_DIS);
557  * }
558  * @endcode
559  *
560  *******************************************************************************
561  */
562 
563 #ifndef ti_drivers_PIN__include
564 #define ti_drivers_PIN__include
565 
566 #include <stdbool.h>
567 #include <stdint.h>
568 
569 #ifdef __cplusplus
570 extern "C" {
571 #endif
572 
584 typedef uint8_t PIN_Id;
585 
587 #define PIN_UNASSIGNED 0xFF
588 #define PIN_TERMINATE 0xFE
590 
604 typedef uint32_t PIN_Config;
605 
616 #define PIN_ID(x) ((x)&0xFF)
617 
618 
635 #define PIN_GEN (((uint32_t)1) << 31)
636 
637 #define PIN_INPUT_EN (PIN_GEN | (0 << 29))
638 #define PIN_INPUT_DIS (PIN_GEN | (1 << 29))
639 #define PIN_HYSTERESIS (PIN_GEN | (1 << 30))
640 #define PIN_NOPULL (PIN_GEN | (0 << 13))
641 #define PIN_PULLUP (PIN_GEN | (1 << 13))
642 #define PIN_PULLDOWN (PIN_GEN | (2 << 13))
643 #define PIN_BM_INPUT_EN (1 << 29)
644 #define PIN_BM_HYSTERESIS (1 << 30)
645 #define PIN_BM_PULLING (0x3 << 13)
646 
647 #define PIN_BM_INPUT_MODE (PIN_BM_INPUT_EN|PIN_BM_HYSTERESIS|PIN_BM_PULLING)
649 
650 #define PIN_GPIO_OUTPUT_DIS (PIN_GEN | (0 << 23))
651 #define PIN_GPIO_OUTPUT_EN (PIN_GEN | (1 << 23))
652 #define PIN_GPIO_LOW (PIN_GEN | (0 << 22))
653 #define PIN_GPIO_HIGH (PIN_GEN | (1 << 22))
654 #define PIN_PUSHPULL (PIN_GEN | (0 << 25))
655 #define PIN_OPENDRAIN (PIN_GEN | (2 << 25))
656 #define PIN_OPENSOURCE (PIN_GEN | (3 << 25))
657 #define PIN_SLEWCTRL (PIN_GEN | (1 << 12))
658 #define PIN_DRVSTR_MIN (PIN_GEN | (0x0 << 8))
659 #define PIN_DRVSTR_MED (PIN_GEN | (0x4 << 8))
660 #define PIN_DRVSTR_MAX (PIN_GEN | (0x8 << 8))
661 #define PIN_BM_GPIO_OUTPUT_EN (1 << 23)
662 #define PIN_BM_GPIO_OUTPUT_VAL (1 << 22)
663 #define PIN_BM_OUTPUT_BUF (0x3 << 25)
664 #define PIN_BM_SLEWCTRL (0x1 << 12)
665 #define PIN_BM_DRVSTR (0xF << 8)
666 
667 #define PIN_BM_OUTPUT_MODE (PIN_BM_GPIO_OUTPUT_VAL | PIN_BM_GPIO_OUTPUT_EN | \
669  PIN_BM_OUTPUT_BUF | PIN_BM_SLEWCTRL | PIN_BM_DRVSTR)
670 
671 #define PIN_INV_INOUT (PIN_GEN | (1 << 24))
672 #define PIN_BM_INV_INOUT (1 << 24)
673 
674 #define PIN_IRQ_DIS (PIN_GEN | (0x0 << 16))
675 #define PIN_IRQ_NEGEDGE (PIN_GEN | (0x5 << 16))
676 #define PIN_IRQ_POSEDGE (PIN_GEN | (0x6 << 16))
677 #define PIN_IRQ_BOTHEDGES (PIN_GEN | (0x7 << 16))
678 #define PIN_BM_IRQ (0x7 << 16)
679 
680 #define PIN_BM_ALL (PIN_BM_INPUT_MODE | PIN_BM_OUTPUT_MODE | PIN_BM_INV_INOUT | PIN_BM_IRQ)
682 
692 typedef struct PIN_State_s PIN_State;
693 
694 
698 typedef PIN_State *PIN_Handle;
699 
700 
710 typedef void (*PIN_IntCb)(PIN_Handle handle, PIN_Id pinId);
711 
712 
715 struct PIN_State_s {
717  uint32_t portMask;
718  uintptr_t userArg;
719  // TODO: add driver-specific field for extensions?
720 };
721 
723 typedef enum {
727  PIN_UNSUPPORTED = 3
728 } PIN_Status;
729 
730 
746 extern PIN_Status PIN_init(const PIN_Config aPinCfg[]);
747 
748 
764 extern PIN_Handle PIN_open(PIN_State *state, const PIN_Config pinList[]);
765 
766 
775 extern PIN_Status PIN_add(PIN_Handle handle, PIN_Config pinCfg);
776 
777 
786 extern PIN_Status PIN_remove(PIN_Handle handle, PIN_Id pinId);
787 
788 
796 extern void PIN_close(PIN_Handle handle);
797 
798 
806 static inline void PIN_setUserArg(PIN_Handle handle, uintptr_t arg) {
807  if (handle) {
808  handle->userArg = arg;
809  }
810 }
811 
812 
820 static inline uintptr_t PIN_getUserArg(PIN_Handle handle) {
821  return handle->userArg;
822 }
823 
824 
843 extern uint32_t PIN_getInputValue(PIN_Id pinId);
844 
845 
862 extern PIN_Status PIN_setOutputEnable(PIN_Handle handle, PIN_Id pinId, bool outputEnable);
863 
864 
878 extern PIN_Status PIN_setOutputValue(PIN_Handle handle, PIN_Id pinId, uint32_t val);
879 
880 
893 extern uint32_t PIN_getOutputValue(PIN_Id pinId);
894 
895 
913 extern PIN_Status PIN_setInterrupt(PIN_Handle handle, PIN_Config pinCfg);
914 
915 
926 extern PIN_Status PIN_clrPendInterrupt(PIN_Handle handle, PIN_Id pinId);
927 
928 
949 extern PIN_Status PIN_registerIntCb(PIN_Handle handle, PIN_IntCb callbackFxn);
950 
951 
952 
972 extern PIN_Config PIN_getConfig(PIN_Id pinId);
973 
974 
988 extern PIN_Status PIN_setConfig(PIN_Handle handle, PIN_Config updateMask, PIN_Config pinCfg);
989 
990 
1013 extern uint32_t PIN_getPortMask(PIN_Handle handle);
1014 
1015 
1025 extern uint32_t PIN_getPortInputValue(PIN_Handle handle);
1026 
1027 
1038 extern uint32_t PIN_getPortOutputValue(PIN_Handle handle);
1039 
1040 
1057 extern PIN_Status PIN_setPortOutputValue(PIN_Handle handle, uint32_t outputValueMask);
1058 
1059 
1077 extern PIN_Status PIN_setPortOutputEnable(PIN_Handle handle, uint32_t outputEnableMask);
1078 
1079 
1083 #ifdef __cplusplus
1084 }
1085 #endif
1086 #endif /* ti_drivers_PIN__include */
uint8_t PIN_Id
Pin identifier data type.
Definition: PIN.h:584
PIN_Status PIN_setInterrupt(PIN_Handle handle, PIN_Config pinCfg)
Control interrupt enable and edge for pin.
Operation not supported.
Definition: PIN.h:726
PIN_Status PIN_setOutputValue(PIN_Handle handle, PIN_Id pinId, uint32_t val)
Control output value for GPIO pin.
PIN_Status PIN_setPortOutputValue(PIN_Handle handle, uint32_t outputValueMask)
Simultaneous write output buffer values of all allocated pins in GPIO port.
PIN_Status PIN_setConfig(PIN_Handle handle, PIN_Config updateMask, PIN_Config pinCfg)
Sets complete pin configuration.
PIN_Status PIN_add(PIN_Handle handle, PIN_Config pinCfg)
Add pin to pin set for open PIN handle.
PIN_Status PIN_init(const PIN_Config aPinCfg[])
PIN module initialization.
uint32_t PIN_getInputValue(PIN_Id pinId)
Get pin input value (0/1)
uint32_t portMask
Bitmask for pins allocated in port.
Definition: PIN.h:716
void(* PIN_IntCb)(PIN_Handle handle, PIN_Id pinId)
I/O Interrupt callback function pointer type One PIN Interrupt callback can be registered by each PIN...
Definition: PIN.h:709
PIN_Handle PIN_open(PIN_State *state, const PIN_Config pinList[])
Allocate one or more pins for a driver or an application.
uintptr_t userArg
User argument for whole handle.
Definition: PIN.h:717
PIN_Config PIN_getConfig(PIN_Id pinId)
Returns pin configuration.
PIN_State * PIN_Handle
A handle that is returned from a PIN_open() call Used for further PIN client interaction with the PIN...
Definition: PIN.h:697
PIN_Status PIN_remove(PIN_Handle handle, PIN_Id pinId)
Removes pin from pin set foropen PIN handle.
uint32_t PIN_getPortInputValue(PIN_Handle handle)
Read input value of whole GPIO port.
underlying data structure for type PIN_State
Definition: PIN.h:714
PIN_Status PIN_setPortOutputEnable(PIN_Handle handle, uint32_t outputEnableMask)
Set output enable for all pins allocated to client in GPIO port.
PIN_Status PIN_setOutputEnable(PIN_Handle handle, PIN_Id pinId, bool outputEnable)
Control output enable for GPIO pin.
PIN_Status
Return value for many functions in the PIN driver interface.
Definition: PIN.h:722
Operation succeeded.
Definition: PIN.h:723
void PIN_close(PIN_Handle handle)
Deallocate all pins previously allocated with a call to PIN_open().
uint32_t PIN_getOutputValue(PIN_Id pinId)
Get value of GPIO pin output buffer.
uint32_t PIN_getPortOutputValue(PIN_Handle handle)
Returns value of whole GPIO port&#39;s output buffers.
PIN_Status PIN_clrPendInterrupt(PIN_Handle handle, PIN_Id pinId)
Clear pending interrupt for pin, if any.
PIN_Status PIN_registerIntCb(PIN_Handle handle, PIN_IntCb callbackFxn)
Register callback function for a set of pins.
Operation failed, client does not have access to pin.
Definition: PIN.h:725
Operation failed, some pin already allocated.
Definition: PIN.h:724
uint32_t PIN_getPortMask(PIN_Handle handle)
Returns bitmask indicating pins allocated to client in GPIO port.
PIN_IntCb callbackFxn
Pointer to interrupt callback function.
Definition: PIN.h:715
uint32_t PIN_Config
Pin configuration data type with embedded pin identifier.
Definition: PIN.h:604
static void PIN_setUserArg(PIN_Handle handle, uintptr_t arg)
Sets a user argument associated with the handle.
Definition: PIN.h:805
static uintptr_t PIN_getUserArg(PIN_Handle handle)
Gets a user argument associated with the handle.
Definition: PIN.h:819
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale