2 * Copyright (c) 2015-2016, Texas Instruments Incorporated
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
33 /*!*****************************************************************************
35 * @brief Generic PIN & GPIO driver
37 * To use the PIN driver ensure that the correct TI-RTOS driver library for your
38 * device is linked in and include this header file:
40 * #include <ti/drivers/PIN.h>
43 * In order to use device-specific functionality or to use the size/speed-
44 * optimized versions of some of the PIN driver functions that circumvent error
45 * and resource checking, link in the correct TI-RTOS driver library for your
46 * device and include the device-specific PIN driver header file (which in turn
47 * includes PIN.h). As an example for the CC26xx family of devices:
49 * #include <ti/drivers/pin/PINCC26xx.h>
53 * The PIN driver allows clients (applications or other drivers) to allocate
54 * and control the I/O pins on the device. The pins can either be software-
55 * controlled general-purpose I/O (GPIO) or connected to hardware peripherals.
56 * Furthermore, the PIN driver allows clients to configure interrupt
57 * functionality on the pins to receive callbacks (and potentially wake up from
58 * the standby or idle power modes) on configurable signal edges.
60 * Most other drivers rely on functionality in the PIN driver.
63 * In order to provide a generic driver interface, this file (PIN.h) only
64 * defines the API and some common data types and macros of the driver. A PIN
65 * client (application or driver) can in most cases only use the generic PIN
66 * API, however, for more advanced usage where device-specific pin
67 * configuration is used or device-specific PIN driver API extensions are
68 * used must use the device-specific PIN driver API.
70 * The device-independent API is implemented as function calls with pin
71 * access control based on the PIN client handle. For time-critical
72 * applications the device-specific API can be used directly, as these
73 * API functions are implemented as inlined functions without access control.
76 * The PIN module provides the following functionality:
77 * - Initialize I/O pins upon boot to a default configuration (possibly
79 * - Provides atomic manipulation of I/O pin hardware registers to allow safe
80 * simultaneous use of I/O pin resources
81 * - I/O pin allocation
82 * - A set of pins can be allocated receiving a pin set handle.
83 * Typically each peripheral driver will allocate a set of pins and an
84 * application must allocate the pins it uses too
85 * - When a pin set is deallocated all the pins in it revert to the state
86 * they were initialized to at boot
87 * - General-purpose I/O (GPIO) services
88 * - Read input buffer value
89 * - Read and set output buffer value
90 * - Read and set output buffer enable
91 * - Access as single pin or port (muliple pins simultaneously)
92 * - Protect pin manipulation
93 * - Pins in an allocated set can only be manipulated using the corresponding
95 * - No handle is needed to read input and output buffer values
96 * - I/O buffer/driver control
97 * - Input mode (detached, hysteresis, pull-up, pull-down)
98 * - Output mode (tristated, push-pull, open drain, open source)
99 * - Output driver strength control
100 * - Output driver slew rate control
101 * - I/O source/target selection (device-specific driver only)
102 * - Map pin to GPIO, peripheral or HW observation signal
103 * - Configuration of I/O interrupt and wakeup from standby
104 * - Interrupt configuration: signal edge to interrupt on, interrupt mask,
105 * callback function registration
106 * - Pins that have enabled interrupts will also wake up the device from low-
107 * power modes like standby and idle upon events
108 * - Provides data types and enums/defines for use in pin configurations
109 * definitions in board files, drivers and applications
111 * ## Pin Allocation ##
112 * The purpose of being able to allocate pins to a pin set is to:
113 * - Manage pin resources
114 * - Give exclusive, protected access to these pins
115 * - Establish a driver state in connection with these pins that allow
116 * functionality such as I/O interrupt callback and I/O port operations
119 * | API function | Description |
120 * |--------------------|------------------------------------------------------|
121 * | PIN_open() | Allocate pins to a set, returns handle |
122 * | PIN_add() | Add pin to pin set for open PIN handle |
123 * | PIN_remove() | Removes pin from pin set for open PIN handle |
124 * | PIN_close() | Deallocate pin set, revert to original GPIO state |
127 * Pins that are to be used as software-controlled general-purpose I/O (GPIO)
128 * need to be allocated in the same manner as for pins that will be mapped to
129 * hardware peripheral ports. A pin set requested with a PIN_open() call may
130 * contain a mix of pins to be used for GPIO and hardware-mapped pins.
132 * When a pin is deallocated using PIN_close() it reverts to the GPIO
133 * configuration it was given in the initial call to PIN_init().
135 * | API function | Description |
136 * |----------------------|---------------------------------------------------|
137 * | PIN_init() | Initialize I/O pins to a safe GPIO state |
138 * | PIN_open() | Allocate pins to a set, returns handle |
139 * | PIN_close() | Deallocate pin set, revert to original GPIO state |
140 * | PIN_setConfig() | Sets parts of or complete pin configuration |
141 * | PIN_getConfig() | Returns pin configuration |
142 * | PIN_setOutputEnable()| Control output enable of GPIO pin |
143 * | PIN_getInputValue() | Read input value on pin |
144 * | PIN_setOutputValue() | Set output value of GPIO pin |
145 * | PIN_getOutputValue() | Get current output value of GPIO pin |
148 * Sometimes it is necessary to be able to read from, write to or control
149 * multiple pins simultaneously (in time). The PIN driver allows a set of
150 * allocated pins, if they reside on the same GPIO port in the underlying
151 * hardware, to be manipulated simultaneously.
153 * | API function | Description |
154 * |--------------------------|---------------------------------------------------|
155 * | PIN_open() | Allocate pins to a set, returns handle |
156 * | PIN_close() | Deallocate pin set, revert to original GPIO state |
157 * | PIN_getPortMask() | Returns bitmask for allocated pins in GPIO port |
158 * | PIN_getPortInputValue() | Returns input value of whole GPIO port |
159 * | PIN_setPortOutputValue() | Sets output value of whole GPIO port (masked) |
160 * | PIN_getPortOutputValue() | Get current output value of whole GPIO port |
161 * | PIN_setPortOutputValue() | Sets output value of whole GPIO port (masked) |
162 * | PIN_setPortOutputEnable()| Sets output enable of whole GPIO port (masked) |
164 * ## I/O Pin Configuration ##
165 * Different devices provide different levels of configurability of I/O pins.
166 * The PIN driver provides a fairly extensive set of @ref PIN_GENERIC_FLAGS
167 * "generic IO configuration options" that are device-independent, all of which
168 * might not be supported by the underlying device-specific PIN driver and
169 * hardware. Likewise, the underlying device-specific PIN driver and hardware
170 * might support additional configuration options not covered by the generic
173 * To allow both independence from and flexibility to use features on the target
174 * device, the #PIN_Config entries used by the PIN driver allows use of either
175 * a set of @ref PIN_GENERIC_FLAGS "generic PIN configuration options" or a
176 * device-specific set of PIN configuration options defined in the underlying
177 * device-specific PIN driver (e.g. PINCC26XX.h)
179 * ### Mapping to GPIO or Peripheral ###
180 * Since the amount of flexibilty in which peripherals can be mapped to which
181 * pins and the manner in which this needs to be set up is highly
182 * device-specific, functions for configuring this is not part of the generic
183 * PIN driver API but is left to be implemented by device-specific PIN drivers.
184 * See the relevant device-specific PIN driver (e.g. PINCC26XX.h) for details.
187 * The input mode of a pin controls:
188 * - Input buffer enable
189 * - Pull-ups or pull-downs
190 * - Hysteresis of input buffer
191 * - Inversion of logical input level
192 * - Potentially, device-specific options
193 * The input mode is set initially with PIN_init() or at a later stage with
194 * PIN_setConfig() and a bitmask with the relevant options
196 * | API function | Description |
197 * |------------------|-------------------------------------------------------|
198 * | PIN_init() | Initialize IOs to a safe GPIO state |
199 * | PIN_getConfig() | Returns pin configuration |
200 * | PIN_setConfig() | Sets parts of or complete pin configuration |
202 * ### Output Mode ###
203 * The output mode of a pin controls:
204 * - Output buffer enable
205 * - Output driver mode (push-pull, open-drain, open-source)
206 * - Output driver slew control
207 * - Output driver current (drive strength)
208 * - Inversion of logical output level
209 * - Potentially, device-specific options
211 * | API function | Description |
212 * |----------------------|---------------------------------------------------|
213 * | PIN_init() | Initialize IOs to a safe GPIO state |
214 * | PIN_setOutputEnable()| Control output enable of GPIO pins |
215 * | PIN_getConfig() | Returns pin configuration |
216 * | PIN_setConfig() | Sets parts of or complete pin configuration |
218 * ### Pin Interrupt and Pin Wakeup ###
219 * Pin interrupts are used to process asynchronous signal edge events on pins
220 * and potentially wake the device up from low power sleep modes. To use pin
221 * interrupts the relevant pins must be allocated and a interrupt callback
222 * registered by the client. The callback function will be called in a SWI
225 * | API function | Description |
226 * |---------------------|----------------------------------------------------|
227 * | PIN_init() | Initialize IOs to a safe GPIO state |
228 * | PIN_getConfig() | Returns pin configuration |
229 * | PIN_setConfig() | Sets parts of or complete pin configuration |
230 * | PIN_setInterrupt() | Control interrupt enable and edge for pin |
231 * | PIN_registerIntCb() | Register callback function for a set of pins |
232 * | PIN_setUserArg() | Sets a user argument associated with the handle |
233 * | PIN_getUserArg() | Gets a user argument associated with the handle |
235 * ## PIN Data Types ##
236 * The PIN driver defines the following data types:
237 * - #PIN_Id: identifies a pin in arguments or lists
238 * - #PIN_Config: provides I/O configuration options for a pin and also embeds
239 * a #PIN_Id identifier. See @ref PIN_GENERIC_FLAGS "available flags/fields"
241 * ## PIN Config Flags/Fields and Bitmasks ##
242 * The PIN driver uses the #PIN_Config data type many places and it merits some
243 * additional attention. A #PIN_Config value consists of a collection of flags
244 * and fields that define how an I/O pin and its attached GPIO interface should
245 * behave electrically and logically. In addition a #PIN_Config value also
246 * embeds a #PIN_Id pin ID, identifying which pin it refers to.
248 * A #PIN_Config value can use one of two mutually exclusive sets of flags and
249 * fields: @ref PIN_GENERIC_FLAGS "device-independent options" defined in
250 * PIN.h or device-dependent options defined in the device-specific
251 * implementation of the PIN driver interface. Any function that uses
252 * #PIN_Config will accept both option types, just not at the same time.
253 * PIN_getConfig() always returns device-independent options, an additional
254 * device-specific version (e.g. PINCC26XX_getConfig()) might return
255 * device-specific options.
257 * The bitmask argument for PIN_setConfig() decides which of the options the
258 * call should affect. All other options are kept at their current values in
259 * hardware. Thus PIN_setConfig(hPins, PIN_BM_PULLING, PIN_BM_PULLUP) will only
260 * change the pullup/pulldown configuration of the pin, leaving everything
261 * else, such as for instance output enable, input hysteresis or output value,
262 * untouched. For #PIN_Config lists (as supplied to PIN_init() for instance)
263 * there is no mask, so all options will affect the pin.
265 * Some of the options affect the pin regardless of whether it is mapped to
266 * a hardware peripheral or GPIO and some options only take effect when it is
267 * mapped to GPIO. These latter options have \_GPIO_ in their names.
269 * The default value for a flag/field is indicated with a star (*) in the
270 * description of the options and will be applied if any explicit value is
271 * not supplied for a flag/field that is masked.
273 * The available options can be grouped into categories as follows:
275 * ### Input Mode Options ###
276 * | Option | Option bitmask | HW/GPIO | Description |
277 * |--------------------|-----------------------|---------|--------------------------------|
278 * |#PIN_INPUT_EN (*) |#PIN_BM_INPUT_EN | Both | Enable pin input buffer |
279 * |#PIN_INPUT_DIS |#PIN_BM_INPUT_EN | Both | Disable pin input buffer |
280 * |#PIN_HYSTERESIS |#PIN_BM_HYSTERESIS | Both | Enable hysteresis on input |
281 * |#PIN_NOPULL (*) |#PIN_BM_PULLING | Both | No pullup/pulldown |
282 * |#PIN_PULLUP |#PIN_BM_PULLING | Both | Enable pullup |
283 * |#PIN_PULLDOWN |#PIN_BM_PULLING | Both | Enable pulldown |
284 * | |#PIN_BM_INPUT_MODE | | Mask for all input mode options|
286 * ### Output Mode Options ###
287 * | Option | Option bitmask | HW/GPIO | Description |
288 * |------------------------|------------------------|---------|----------------------------------|
289 * |#PIN_GPIO_OUTPUT_DIS (*)|#PIN_BM_GPIO_OUTPUT_EN | GPIO | Disable GPIO output buffer |
290 * |#PIN_GPIO_OUTPUT_EN |#PIN_BM_GPIO_OUTPUT_EN | GPIO | Enable GPIO output buffer |
291 * |#PIN_GPIO_LOW (*) |#PIN_BM_GPIO_OUTPUT_VAL | GPIO | Output 0 when GPIO |
292 * |#PIN_GPIO_HIGH |#PIN_BM_GPIO_OUTPUT_VAL | GPIO | Output 1 when GPIO |
293 * |#PIN_PUSHPULL (*) |#PIN_BM_OUTPUT_BUF | Both | Use push-pull output buffer |
294 * |#PIN_OPENDRAIN |#PIN_BM_OUTPUT_BUF | Both | Use open drain output buffer |
295 * |#PIN_OPENSOURCE |#PIN_BM_OUTPUT_BUF | Both | Use open source output buffer |
296 * |#PIN_SLEWCTRL |#PIN_BM_SLEWCTRL | Both | Enable output buffer slew control|
297 * |#PIN_DRVSTR_MIN (*) |#PIN_BM_DRVSTR | Both | Output buffer uses min drive |
298 * |#PIN_DRVSTR_MED |#PIN_BM_DRVSTR | Both | Output buffer uses medium drive |
299 * |#PIN_DRVSTR_MAX |#PIN_BM_DRVSTR | Both | Output buffer uses max drive |
300 * | |#PIN_BM_OUTPUT_MODE | | Mask for all output mode options |
302 * ### Misc Options ###
303 * | Option | Option bitmask | HW/GPIO | Description |
304 * |-------------------|------------------|---------|----------------------------------|
305 * |#PIN_INV_INOUT |#PIN_BM_INV_INOUT | Both | Invert input/output |
306 * |#PIN_IRQ_DIS (*) |#PIN_BM_IRQ | Both | Disable pin interrupts |
307 * |#PIN_IRQ_NEGEDGE |#PIN_BM_IRQ | Both | Pin interrupts on negative edges |
308 * |#PIN_IRQ_POSEDGE |#PIN_BM_IRQ | Both | Pin interrupts on negative edges |
309 * |#PIN_IRQ_BOTHEDGES |#PIN_BM_IRQ | Both | Pin interrupts on both edges |
310 * | |#PIN_BM_ALL | | Mask for *all* options |
312 * ## Initialization ##
313 * The PIN driver must be initialized before any other drivers are initialized.
314 * In order for IO pins to get a safe value as soon as possible PIN_init()
315 * should be called as early as possible in the boot sequence. Typically,
316 * PIN_init() is called at the start of main() before TI-RTOS is started with
319 * PIN_init() takes as an argument a #PIN_Config list containing default pin
320 * configurations. Typically the #PIN_Config list defined in the board files
323 * PIN_init(BoardGpioInitTable);
325 * It is possible, however, to use another #PIN_Config list if desired.
327 * ## Power Management Interaction ##
328 * No specific interaction with power management module, as PIN is independent
331 * ## Functionality Not Supported ##
332 * There is no known unsupported functionality.
334 * ## Instrumentation ##
335 * The pin driver does not use any of the instrumentation facilities.
339 * ## Initialization and Pin Allocation ##
340 * Example that illustrates when and how to call PIN_init(), PIN_open(), PIN_add(), PIN_close()
342 * // Default pin configuration. Typically resides in Board.c file.
343 * // IOs not mentioned here configured to default: input/output/pull disabled
344 * PIN_Config BoardGpioInitTable[] = {
345 * // DIO11: LED A (initially off)
346 * PIN_ID(11) | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
347 * // DIO10: LED B (initially off)
348 * PIN_ID(10) | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
349 * // DIO23: BUTTON A (ensure pull-up as button A is also used by other ICs)
350 * PIN_ID(23) | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,
351 * // DIO3: LCD controller reset line (make sure LCD is in reset)
352 * PIN_ID(3) | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
357 * Task_Struct taskStart;
358 * uint8_t taskStartStack[512];
360 * // PIN_init() should be called as early as possible in boot
362 * // Default initialization of IO
363 * PIN_init(BoardGpioInitTable);
365 * // Configure startup task
366 * Task_Params taskParams;
367 * Task_Params_init(&taskParams);
368 * taskParams.stack = taskStartStack;
369 * taskParams.stackSize = sizeof(taskStartStack);
370 * Task_construct(&taskStart, taskStartFxn, &taskParams, NULL);
372 * // Start kernel (never returns)
376 * // Human user interface PIN state/handle
377 * PIN_State hStateHui;
378 * #define HUI_LED_A PIN_ID(11)
379 * #define HUI_LED_B PIN_ID(10)
380 * #define HUI_LED_C PIN_ID(9)
381 * #define HUI_BUTTON_A PIN_ID(23)
382 * #define HUI_BUTTON_B PIN_ID(24)
384 * static void taskStartFxn(UArg a0, UArg a1) {
385 * // Define pins used by Human user interface and initial configuration
386 * const PIN_Config aPinListHui[] = {
387 * HUI_LED_A | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
388 * HUI_LED_B | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
389 * HUI_BUTTON_A | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,
390 * HUI_BUTTON_B | PIN_INPUT_EN | PIN_PULLUP | PIN_HYSTERESIS,
394 * // Get handle to this collection of pins
395 * if (!PIN_open(&hStateHui, aPinListHui)) {
396 * // Handle allocation error
401 * // We can also add (and remove) pins to a set at run time
402 * PIN_Status status = PIN_add(
404 * HUI_LED_C | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
406 * if (status != PIN_SUCCESS) {
407 * // Handling allocation error is especially important with PIN_add()
413 * // Before ending task, make sure to deallocate pins. They will return
414 * // to the default configurations provided in PIN_init()
415 * PIN_close(&hStateHui);
419 * ## Application use of GPIO ##
420 * An example of using GPIO that builds on the previous example. Illustrates how
421 * to read input values, set output values and control output enable
423 * void huiDoSomething() {
424 * // Running lights on LEDs A-B-C (left to right). Button A causes left
425 * // movement, button B causes right movement, both simultaneously aborts
426 * // and disables LED output drivers
428 * // LED initial state (A off, B off, C on). Only our outputs are affected
429 * PIN_setPortOutputValue(&hStateHui, (1<<HUI_LED_C));
431 * int32_t moveDir = -1; // <0: left, 0: stop, >0 right
436 * uint32_t t = PIN_getOutputValue(HUI_LED_A);
437 * PIN_setOutputValue(&hStateHui, HUI_LED_A, PIN_getOutputValue(HUI_LED_B));
438 * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_C));
439 * PIN_setOutputValue(&hStateHui, HUI_LED_C, t);
442 * uint32_t t = PIN_getOutputValue(HUI_LED_C);
443 * PIN_setOutputValue(&hStateHui, HUI_LED_C, PIN_getOutputValue(HUI_LED_B));
444 * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_A));
445 * PIN_setOutputValue(&hStateHui, HUI_LED_A, t);
448 * // Sleep for 333 ms
449 * Task_sleep(333000/10);
451 * // Read input from both buttons simultaneously
452 * uint32_t buttons = PIN_getPortInputValue(&hStateHui);
453 * if (buttons&(1<<HUI_BUTTON_A) == 0) {
455 * } else if (buttons&(1<<HUI_BUTTON_A) == 0) {
457 * } else if (buttons&((1<<HUI_BUTTON_A)|(1<<HUI_BUTTON_A))) {
461 * // Disable output enable for all pins (only our pins affected)
462 * PIN_setPortOutputEnable(&hStateHui, 0);
466 * ## Pin Interrupt ##
467 * An example that handles pin inputs in the GPIO example above using PIN interrupts
470 * // volatile variable used to communicate between callback and task
471 * static volatile int32_t moveDir = -1; // <0: left, 0: stop, >0 right
473 * // Pin interrupt callback
474 * void huiPinIntCb(PIN_Handle handle, PIN_Id pinId) {
475 * // Ignore pinId and read input from both buttons simultaneously
476 * uint32_t buttons = PIN_getPortInputValue(&hStateHui);
477 * if (buttons&(1<<HUI_BUTTON_A) == 0) {
479 * } else if (buttons&(1<<HUI_BUTTON_A) == 0) {
481 * } else if (buttons&((1<<HUI_BUTTON_A)|(1<<HUI_BUTTON_A))) {
486 * void huiDoSomething() {
487 * // Running lights on LEDs A-B-C (left to right). Button A causes left
488 * // movement, button B causes right movement, both simultaneously aborts
489 * // and disables LED output drivers
491 * // LED initial state (A off, B off, C on). Only our outputs are affected
492 * PIN_setPortOutputValue(&hStateHui, (1<<HUI_LED_C));
493 * moveDir = -1; // <0: left, 0: stop, >0 right
495 * // Setup pin interrupts and register callback
496 * PIN_registerIntCb(&hStateHui, huiPinIntCb);
497 * PIN_setInterrupt(&hStateHui, HUI_BUTTON_A | PIN_IRQ_NEGEDGE);
498 * PIN_setInterrupt(&hStateHui, HUI_BUTTON_B | PIN_IRQ_NEGEDGE);
504 * uint32_t t = PIN_getOutputValue(HUI_LED_A);
505 * PIN_setOutputValue(&hStateHui, HUI_LED_A, PIN_getOutputValue(HUI_LED_B));
506 * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_C));
507 * PIN_setOutputValue(&hStateHui, HUI_LED_C, t);
510 * uint32_t t = PIN_getOutputValue(HUI_LED_C);
511 * PIN_setOutputValue(&hStateHui, HUI_LED_C, PIN_getOutputValue(HUI_LED_B));
512 * PIN_setOutputValue(&hStateHui, HUI_LED_B, PIN_getOutputValue(HUI_LED_A));
513 * PIN_setOutputValue(&hStateHui, HUI_LED_A, t);
516 * // Sleep for 333 ms (we will likely go into standby)
517 * Task_sleep(333000/10);
519 * // Disable output enable for all pins (only our pins affected)
520 * PIN_setPortOutputEnable(&hStateHui, 0);
521 * // Disable pin interrupts
522 * PIN_setInterrupt(&hStateHui, HUI_BUTTON_A | PIN_IRQ_DIS);
523 * PIN_setInterrupt(&hStateHui, HUI_BUTTON_B | PIN_IRQ_DIS);
527 *******************************************************************************
530 #ifndef ti_drivers_PIN__include
531 #define ti_drivers_PIN__include
540 //#include <inc/hw_types.h>
542 typedef unsigned int uint_t;
546 /** @brief Pin identifier data type
548 * Data type used to identify a pin through an index between 0 to 254.
549 * Typically the index does not refer to the physical device pin number but
550 * rather to the index of the subset of pins that are under software-control
551 * (e.g. index 3 refers to DIO3).
552 * This data type is used as arguments in API functions to identify which pin
553 * is affected or used in lists (terminated by #PIN_TERMINATE entry) identifying
557 typedef uint8_t PIN_Id;
559 /// Pin ID used to indicate no pin
560 #define PIN_UNASSIGNED 0xFF
561 /// Pin ID used to terminate a list of PIN_Id or PIN_Config entries
562 #define PIN_TERMINATE 0xFE
564 /** @brief Pin configuration data type with embedded pin identifier
566 * A data type used to specify I/O-pin configuration options. The lower 8b
567 * contain an embedded pin ID (see #PIN_Id) and the top 24b contain
568 * flags/fields that affect I/O configuration. #PIN_Config entries can either
569 * use a @ref PIN_GENERIC_FLAGS "set of device-independent options" or
570 * device-specific options defined in PIN driver (e.g. PINCC26XX.h), but cannot
573 * This data type is used as arguments or return values in API functions that
574 * manipulate pin configuration or used in lists (terminated by a
575 * #PIN_TERMINATE entry) for configuring multiple pins at a time.
577 typedef uint32_t PIN_Config;
579 /** @brief Macro for inserting or extracting a #PIN_Id in a #PIN_Config entry
582 * PIN_Config pinCfg = PIN_ID(5) | PIN_GPIO_OUTPUT_EN | PIN_PUSHPULL |
583 * PIN_GPIO_HIGH | PIN_IRQ_POSEDGE;
584 * PIN_setConfig(hPins, PIN_BM_OUTPUT_MODE, pinCfg);
586 * PIN_setOutputValue(hPins, PIN_ID(pinCfg), 1);
589 #define PIN_ID(x) ((x)&0xFF)
592 /** @anchor PIN_GENERIC_FLAGS
593 * @name Generic PIN_Config flags/fields
594 * Generic (i.e. not device-specific) fields/flags for I/O configuration for
595 * use in #PIN_Config entries. All of these generic options may not be
596 * supported by the underlying device-specific PIN driver. A #PIN_Config
597 * entry may use either these generic fields/flags or device-specific ones
598 * defined in the device-specific PIN-driver, but may not mix the two.
600 * The entries starting with PIN_BM_ are bitmasks used to extract individual
601 * fields obtained from PIN_getConfig() or to pass as a parameter to
602 * PIN_setConfig()to define which options it should set.
604 * A star (*) in the descriptions below means the default if no option is
608 #define PIN_GEN (((uint32_t)1)<<31) ///< Flags that generic options are used
610 #define PIN_INPUT_EN (PIN_GEN|(0<<29)) ///< (*) Enable input buffer
611 #define PIN_INPUT_DIS (PIN_GEN|(1<<29)) ///< Disable input buffer
612 #define PIN_HYSTERESIS (PIN_GEN|(1<<30)) ///< Enable input buffer hysteresis
613 #define PIN_NOPULL (PIN_GEN|(0<<13)) ///< (*) No pull-up or pull-down resistor
614 #define PIN_PULLUP (PIN_GEN|(1<<13)) ///< Pull-up resistor enabled
615 #define PIN_PULLDOWN (PIN_GEN|(2<<13)) ///< Pull-down resistor enabled
616 #define PIN_BM_INPUT_EN (1<<29) ///< Bitmask for input enable option
617 #define PIN_BM_HYSTERESIS (1<<30) ///< Bitmask input hysteresis option
618 #define PIN_BM_PULLING (0x3<<13) ///< Bitmask for pull-up/pull-down options
620 /// Bitmask for all input mode options
621 #define PIN_BM_INPUT_MODE (PIN_BM_INPUT_EN|PIN_BM_HYSTERESIS|PIN_BM_PULLING)
623 #define PIN_GPIO_OUTPUT_DIS (PIN_GEN|(0<<23)) ///< (*) Disable output buffer when GPIO
624 #define PIN_GPIO_OUTPUT_EN (PIN_GEN|(1<<23)) ///< Enable output buffer when GPIO
625 #define PIN_GPIO_LOW (PIN_GEN|(0<<22)) ///< Output buffer drives to VSS when GPIO
626 #define PIN_GPIO_HIGH (PIN_GEN|(1<<22)) ///< Output buffer drives to VDD when GPIO
627 #define PIN_PUSHPULL (PIN_GEN|(0<<25)) ///< (*) Output buffer mode: push/pull
628 #define PIN_OPENDRAIN (PIN_GEN|(2<<25)) ///< Output buffer mode: open drain
629 #define PIN_OPENSOURCE (PIN_GEN|(3<<25)) ///< Output buffer mode: open source
630 #define PIN_SLEWCTRL (PIN_GEN|(1<<12)) ///< Enable output buffer slew control
631 #define PIN_DRVSTR_MIN (PIN_GEN|(0x0<<8)) ///< (*) Lowest drive strength
632 #define PIN_DRVSTR_MED (PIN_GEN|(0x4<<8)) ///< Medium drive strength
633 #define PIN_DRVSTR_MAX (PIN_GEN|(0x8<<8)) ///< Highest drive strength
634 #define PIN_BM_GPIO_OUTPUT_EN (1<<23) ///< Bitmask for output enable option
635 #define PIN_BM_GPIO_OUTPUT_VAL (1<<22) ///< Bitmask for output value option
636 #define PIN_BM_OUTPUT_BUF (0x3<<25) ///< Bitmask for output buffer options
637 #define PIN_BM_SLEWCTRL (0x1<<12) ///< Bitmask for slew control options
638 #define PIN_BM_DRVSTR (0xF<<8) ///< Bitmask for drive strength options
640 /// Bitmask for all output mode options
641 #define PIN_BM_OUTPUT_MODE (PIN_BM_GPIO_OUTPUT_VAL|PIN_BM_GPIO_OUTPUT_EN| \
642 PIN_BM_OUTPUT_BUF|PIN_BM_SLEWCTRL|PIN_BM_DRVSTR)
644 #define PIN_INV_INOUT (PIN_GEN|(1<<24)) ///< Logically invert input and output
645 #define PIN_BM_INV_INOUT (1<<24) ///< Bitmask for input/output inversion option
647 #define PIN_IRQ_DIS (PIN_GEN|(0x0<<16)) ///< (*) Disable IRQ on pin
648 #define PIN_IRQ_NEGEDGE (PIN_GEN|(0x5<<16)) ///< Enable IRQ on negative edge
649 #define PIN_IRQ_POSEDGE (PIN_GEN|(0x6<<16)) ///< Enable IRQ on positive edge
650 #define PIN_IRQ_BOTHEDGES (PIN_GEN|(0x7<<16)) ///< Enable IRQ on both edges
651 #define PIN_BM_IRQ (0x7<<16) ///< Bitmask for pin interrupt option
653 /// Bitmask for all options at once
654 #define PIN_BM_ALL (PIN_BM_INPUT_MODE|PIN_BM_OUTPUT_MODE|PIN_BM_INV_INOUT|PIN_BM_IRQ)
655 /** \} (PIN_GENERIC_FLAGS)
659 /** @brief Struct used to store PIN client state
660 * Pointer to a PIN_State is used as handles (#PIN_Handle) in interactions with
662 * @note Must reside in persistent memory
663 * @note Fields must never be modified directly
665 typedef struct PIN_State_s PIN_State;
668 /** @brief A handle that is returned from a PIN_open() call
669 * Used for further PIN client interaction with the PIN driver
671 typedef PIN_State* PIN_Handle;
674 /** @brief I/O Interrupt callback function pointer type
675 * One PIN Interrupt callback can be registered by each PIN client and it
676 * will be called when one of the pins allocated by the client has an interrupt
677 * event. The callback is called from HWI context with handle and pin ID as
679 * @remark The callback must, as it runs in HWI context, execute and return
680 * quickly. Any lengthy operations should be performed in SWIs or tasks
681 * triggered by the callback
683 typedef void (*PIN_IntCb)(PIN_Handle handle, PIN_Id pinId);
686 /** @brief underlying data structure for type #PIN_State
689 PIN_IntCb pCbFunc; ///< Pointer to interrupt callback function
690 uint_t bmPort; ///< Bitmask for pins allocated in port
691 UArg userArg; ///< User argument for whole handle
692 // TODO: add driver-specific field for extensions?
695 /// @brief Return value for many functions in the PIN driver interface
697 PIN_SUCCESS = 0, ///< Operation succeeded
698 PIN_ALREADY_ALLOCATED = 1, ///< Operation failed, some pin already allocated
699 PIN_NO_ACCESS = 2, ///< Operation failed, client does not have access to pin
700 PIN_UNSUPPORTED = 3 ///< Operation not supported
704 /** @brief PIN module initialization
706 * Must be called early in the boot sequence to ensure that I/O pins have safe
707 * configurations. This initialization sets up pins as GPIO as defined in an
708 * array (possibly user-generated) that typically resides in a board file. All
709 * pins not mentioned in aPinCfg[] are configured to be input/output/pull
712 * @note Function *cannot* be called more than once.
714 * @param aPinCfg[] Pointer to array of PIN_Config entries, one per pin
715 * that needs configuration. List terminates when a
716 * #PIN_TERMINATE entry is encountered.
717 * @return #PIN_SUCCESS if successful, else an error code.
719 extern PIN_Status PIN_init(const PIN_Config aPinCfg[]);
722 /** @brief Allocate one or more pins for a driver or an application
724 * Allows a PIN client (driver or application) to allocate a set of pins, thus
725 * ensuring that they cannot be reconfigured/controlled by anyone else. The
726 * pins are identified by and reconfigured according to the #PIN_Config
727 * entries in aPinList.
729 * @param pState Pointer to a PIN_State object that will hold the state for
730 * this IO client. The object must be in persistent memory
731 * @param aPinList[] Pointer to array of #PIN_Config entries, one per pin to
732 * allocate. List terminates when #PIN_TERMINATE entry is
734 * @return A handle for further PIN driver calls or NULL if an error occurred
735 * (already allocated pin in aPinList or non-existent pin in aPinList)
737 extern PIN_Handle PIN_open(PIN_State* pState, const PIN_Config aPinList[]);
740 /** @brief Add pin to pin set for open PIN handle
742 * If the requested pin is unallocated it will be added, else an error code
744 * @param handle handle retrieved through an earlier call to PIN_open().
745 * @param pinCfg Pin ID/configuration for pin to add.
746 * @return Error code if unsuccessful, else PIN_SUCCESS
748 extern PIN_Status PIN_add(PIN_Handle handle, PIN_Config pinCfg);
751 /** @brief Removes pin from pin set foropen PIN handle
753 * If the requested pin is allocated to handle it will be removed from the pin
754 * set, else an error code will be returned.
755 * @param handle handle retrieved through an earlier call to PIN_open().
756 * @param pinId Pin ID for pin to remove.
757 * @return Error code if unsuccessful, else PIN_SUCCESS
759 extern PIN_Status PIN_remove(PIN_Handle handle, PIN_Id pinId);
762 /** @brief Deallocate all pins previously allocated with a call to PIN_open().
764 * Deallocate pins allocated to handle and restore these pins to the
765 * pool of unallocated pins. Also restores the pin configuration to what it was
766 * set to when PIN_init() was called.
767 * @param handle handle retrieved through an earlier call to PIN_open().
769 extern void PIN_close(PIN_Handle handle);
772 /** @brief Sets a user argument associated with the handle
774 * Allows the application to store some data, for example a pointer to some
775 * data structure, with each PIN handle
776 * @param handle handle retrieved through an earlier call to PIN_open().
777 * @param arg User argument
779 static inline void PIN_setUserArg(PIN_Handle handle, UArg arg) {
781 handle->userArg = arg;
786 /** @brief Gets a user argument associated with the handle
788 * Allows the application to store some data, for example a pointer to some
789 * data structure, with each PIN handle
790 * @param handle handle retrieved through an earlier call to PIN_open().
791 * @return User argument. Has the value 0 if never initialized
793 static inline UArg PIN_getUserArg(PIN_Handle handle) {
794 return handle->userArg;
798 /** @name Pin Manipulation/Configuration Functions
799 * Functions that are used to manipulate the configuration of I/O pins and to
800 * get input values and set output values.
804 /** @brief Get pin input value (0/1)
806 * Input values of all pins are available to everyone so no handle required
807 * @param pinId ID of pin to get input value from
808 * @return Current input buffer value
809 * @remark This function typically has an inlined sibling function in the
810 * device-specific driver that may be used for higher efficiency
813 * myPin = PIN_getInputValue(PIN_ID(5));
816 extern uint_t PIN_getInputValue(PIN_Id pinId);
819 /** @brief Control output enable for GPIO pin
821 * @param handle Handle provided by previous call to PIN_open()
822 * @param pinId #PIN_Id entry identifying pin
823 * @param bOutEn Enable output buffer when true, else disable
824 * @return #PIN_SUCCESS if successful, else error code
825 * @remark This function is included for consistency with the corresponding
826 * port function and to provide a more efficient/directed approach.
827 * PIN_setConfig() can be used to achieve same result.
828 * @remark This function typically has an inlined sibling function in the
829 * device-specific driver that may be used for higher efficiency
832 * PIN_setOutputEnable(hPins, PIN_ID(11), 0);
835 extern PIN_Status PIN_setOutputEnable(PIN_Handle handle, PIN_Id pinId, bool bOutEn);
838 /** @brief Control output value for GPIO pin
840 * @param handle Handle provided by previous call to PIN_open()
841 * @param pinId Pin ID
842 * @param val Output value (0/1)
843 * @return #PIN_SUCCESS if successful, else error code
844 * @remark This function typically has an inlined sibling function in the
845 * device-specific driver that may be used for higher efficiency
848 * PIN_setOutputValue(hPins, PIN_ID(4), 1);
851 extern PIN_Status PIN_setOutputValue(PIN_Handle handle, PIN_Id pinId, uint_t val);
854 /** @brief Get value of GPIO pin output buffer
856 * Output values of all pins are available to everyone so no handle required
857 * @param pinId Pin ID
858 * @return Output value (0/1)
859 * @remark This function typically has an inlined sibling function in the
860 * device-specific driver that may be used for higher efficiency
863 * PIN_setOutputValue(hpins, PIN_ID(4), PIN_getOutputValue(PIN_ID(6)));
866 extern uint_t PIN_getOutputValue(PIN_Id pinId);
869 /** @brief Control interrupt enable and edge for pin
871 * @param handle Handle provided by previous call to PIN_open()
872 * @param pinCfg #PIN_Config entry identifying pin ID and relevant pin
873 * configuration as combinations of:
874 * - #PIN_IRQ_DIS (default)
877 * - #PIN_IRQ_BOTHEDGES
878 * @return #PIN_SUCCESS if successful, else error code
879 * @note Any pending interrupts on pins that have not had interrupt enabled
880 * will be cleared when enabling interrupts
883 * PIN_setInterrupt(hPins, PIN_ID(8)|PIN_IRQ_POSEDGE);
886 extern PIN_Status PIN_setInterrupt(PIN_Handle handle, PIN_Config pinCfg);
889 /** @brief Clear pending interrupt for pin, if any
891 * @param handle Handle provided by previous call to PIN_open()
892 * @param pinId #PIN_Id for pin to clear pending interrupt for
893 * @return #PIN_SUCCESS if successful, else error code
896 * PIN_ClrPendInterrupt(hPins, PIN_ID(8));
899 extern PIN_Status PIN_clrPendInterrupt(PIN_Handle handle, PIN_Id pinId);
902 /** @brief Register callback function for a set of pins
904 * Registers a callback function (see #PIN_IntCb for details) for the client
905 * identified by handle that will be called from HWI context upon an interrupt
906 * event on one or more of the allocated pins that have interrupts enabled
907 * @param handle Handle provided by previous call to PIN_open()
908 * @param pCb Function pointer to a #PIN_IntCb function.
909 * @return #PIN_SUCCESS if successful, else error code
910 * @note Pin interrupts are serviced one at a time in pin order when
911 * simultaneous. Pin hardware interrupt flags are automatically cleared
915 * void pinIntHandler(PIN_Handle handle, PIN_Id pinId) {
916 * // Handle pin interrupt
919 * PIN_registerIntCb(hPins, pinIntHandler);
922 extern PIN_Status PIN_registerIntCb(PIN_Handle handle, PIN_IntCb pCb);
926 /** @brief Returns pin configuration
928 * @param pinId Pin ID
929 * @return Current pin configuration as a device-independent #PIN_Config value
930 * @note The pin ID is embedded in return value.
931 * @note There is usually a device-specific version of this function that
932 * returns device-specific options
935 * // Get config of pin 14 to be able to revert later
936 * myPinConfig = PIN_getConfig(PIN_ID(14));
938 * // Lots of pin reconfigurations
940 * // Restore previous configuration
941 * PIN_setConfig(hPins, PIN_BM_ALL, myPinConfig);
944 extern PIN_Config PIN_getConfig(PIN_Id pinId);
947 /** @brief Sets complete pin configuration
949 * @param handle Handle provided by previous call to PIN_open()
950 * @param bmMask Bitmask specifying which fields in cfg that should take
951 * effect, the rest keep their current value.
952 * @param pinCfg #PIN_Config entry with pin ID and pin configuration
953 * @return #PIN_SUCCESS if successful, else error code
956 * // Set drive strength on pin 15
957 * PIN_setConfig(hPins, PIN_BM_DRVSTR, PIN_ID(15)|PIN_DRVSTR_MAX);
960 extern PIN_Status PIN_setConfig(PIN_Handle handle, PIN_Config bmMask, PIN_Config pinCfg);
963 /** \} (IO Manipulation/Configuration Functions)
967 /** @name IO Port Functions
968 * Functions used to get input values for, set ouput values for and set output
969 * enables for multiple pins at a time. The size of so-called I/O ports that
970 * allows such multiple-pin operations are highly device dependent. In order to
971 * use the I/O port functions a set of pins that reside in the same I/O port
972 * must have been allocated previously with PIN_open().
977 /** @brief Returns bitmask indicating pins allocated to client in GPIO port
979 * @param handle Handle provided by previous call to PIN_open()
980 * @return A bitmask indicating which bit positions in an I/O port the
981 * allocated I/O pins lie on, or zero if I/O port operations are not
982 * supported or the allocated pins span multiple I/O ports. The bitmask
983 * maps lowest pin index to the rightmost mask bit
985 extern uint_t PIN_getPortMask(PIN_Handle handle);
988 /** @brief Read input value of whole GPIO port
990 * @param handle Handle provided by previous call to PIN_open()
991 * @return The simultaneous input value for the whole I/O port masked by the
992 * bit mask for the client's allocated pins
993 * @sa PIN_getPortMask()
994 * @remark This function typically has an inlined sibling function in the
995 * device-specific driver that may be used for higher efficiency
997 extern uint_t PIN_getPortInputValue(PIN_Handle handle);
1000 /** @brief Returns value of whole GPIO port's output buffers
1002 * The I/O port is identified by the pins allocated by client in a previous
1003 * call to PIN_open()
1004 * @param handle Handle provided by previous call to PIN_open()
1005 * @return The current output value for whole I/O port
1006 * @sa PIN_getPortMask()
1007 * @remark This function typically has an inlined sibling function in the
1008 * device-specific driver that may be used for higher efficiency
1010 extern uint_t PIN_getPortOutputValue(PIN_Handle handle);
1013 /** @brief Simultaneous write output buffer values of all allocated pins in GPIO port
1015 * @param handle Handle provided by previous call to PIN_open()
1016 * @param bmOutVal Bitmask indicating the desired output value for the whole
1017 * port, only the pins allocated to the client will be
1019 * @return #PIN_SUCCESS if successful, else error code
1020 * @sa PIN_getPortMask()
1021 * @remark This function typically has an inlined sibling function in the
1022 * device-specific driver that may be used for higher efficiency
1025 * // Invert all pins allocated to client
1026 * PIN_setPortOutputVal(hPins, ~PIN_getPortOutputVals(hPins));
1029 extern PIN_Status PIN_setPortOutputValue(PIN_Handle handle, uint_t bmOutVal);
1032 /** @brief Set output enable for all pins allocated to client in GPIO port
1034 * @param handle Handle provided by previous call to PIN_open()
1035 * @param bmOutEn Bitmask indicating the desired output enable configuration
1036 * for the whole port, only the pins allocated to the client
1038 * @return #PIN_SUCCESS if successful, else error code
1039 * @sa PIN_getPortMask()
1040 * @remark This function typically has an inlined sibling function in the
1041 * device-specific driver that may be used for higher efficiency
1044 * // Set output to 0 on all allocated pins, then enable the output drivers
1045 * pin_setPortOutputVal(hPins, 0);
1046 * pin_setPortOutputEnable(hPins, PIN_getPortMask());
1049 extern PIN_Status PIN_setPortOutputEnable(PIN_Handle handle, uint_t bmOutEn);
1052 /** \} (IO Port Functions)
1058 #endif /* ti_drivers_PIN__include */