1 /* 2 * Copyright (c) 2015-2020, 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 GPIO.h 34 * 35 * @brief General Purpose I/O driver interface. 36 * 37 * The GPIO header file should be included in an application as follows: 38 * @code 39 * #include <ti/drivers/GPIO.h> 40 * @endcode 41 * 42 * # Overview # 43 * The GPIO module allows you to manage General Purpose I/O pins via simple 44 * and portable APIs. GPIO pin behavior is usually configured statically, 45 * but can also be configured or reconfigured at runtime. 46 * 47 * Because of its simplicity, the GPIO driver does not follow the model of 48 * other TI-RTOS drivers in which a driver application interface has 49 * separate device-specific implementations. This difference is most 50 * apparent in the GPIOxxx_Config structure, which does not require you to 51 * specify a particular function table or object. 52 * 53 * # Usage # 54 * This section provides a basic \ref ti_drivers_GPIO_Synopsis 55 * "usage summary" and a set of \ref ti_drivers_GPIO_Examples "examples" 56 * in the form of commented code fragments. Detailed descriptions of the 57 * GPIO APIs and their effect are provided in subsequent sections. 58 * 59 * @anchor ti_drivers_GPIO_Synopsis 60 * ### Synopsis # 61 * @anchor ti_drivers_GPIO_Synopsis_Code 62 * @code 63 * // Import GPIO Driver definitions 64 * #include <ti/drivers/GPIO.h> 65 * 66 * // Define names for GPIO pin indexes 67 * #define BUTTON 0 68 * #define LED 1 69 * 70 * // One-time init of GPIO driver 71 * GPIO_init(); 72 * 73 * // Read GPIO pin 74 * unsigned int state = GPIO_read(BUTTON); 75 * 76 * // Write to GPIO pin 77 * GPIO_write(LED, state); 78 * @endcode 79 * 80 * @anchor ti_drivers_GPIO_Examples 81 * ### Examples # 82 * * @ref ti_drivers_GPIO_Example_callback "Creating an input callback" 83 * * @ref ti_drivers_GPIO_Example_reconfigure "Runtime pin configuration" 84 * 85 * @anchor ti_drivers_GPIO_Example_callback 86 * **Creating an input callback**: The following example demonstrates how 87 * to configure a GPIO pin to generate an interrupt and how to toggle an 88 * an LED on and off within the registered interrupt callback function. 89 * @code 90 * // Driver header file 91 * #include <ti/drivers/GPIO.h> 92 * 93 * // TI Drivers Configuration 94 * #include "ti_drivers_config.h" 95 * // Board file 96 * #include <ti/drivers/Board.h> 97 * 98 * // GPIO button call back function 99 * void gpioButton0Fxn(uint_least8_t index); 100 * 101 * main() 102 * { 103 * // One-time Board initialization 104 * Board_init(); 105 * 106 * // One-time init of GPIO driver 107 * GPIO_init(); 108 * 109 * // Turn on user LED 110 * GPIO_write(CONFIG_GPIO_LED0, CONFIG_GPIO_LED_ON); 111 * 112 * // install Button callback 113 * GPIO_setCallback(CONFIG_GPIO_BUTTON0, gpioButton0Fxn); 114 * 115 * // Enable interrupts 116 * GPIO_enableInt(CONFIG_GPIO_BUTTON0); 117 * } 118 * 119 * // 120 * // ======== gpioButton0Fxn ======== 121 * // Callback function for the GPIO interrupt on CONFIG_GPIO_BUTTON0 122 * // 123 * // Note: index is the GPIO id for the button which is not used here 124 * // 125 * void gpioButton0Fxn(uint_least8_t index) 126 * { 127 * // Toggle the LED 128 * GPIO_toggle(CONFIG_GPIO_LED0); 129 * } 130 * @endcode 131 * 132 * @anchor ti_drivers_GPIO_Example_reconfigure 133 * **Runtime pin configuration**: The following example demonstrates how 134 * to (re)configure GPIO pins. 135 * @code 136 * // Driver header file 137 * #include <ti/drivers/GPIO.h> 138 * 139 * // TI Driver configuration 140 * #include "ti_drivers_config.h" 141 * 142 * #define LED CONFIG_GPIO_LED0 143 * #define BUTTON CONFIG_GPIO_BUTTON0 144 * 145 * void main() 146 * { 147 * // One-time init of GPIO driver 148 * GPIO_init(); 149 * 150 * // Configure a button input pin 151 * GPIO_setConfig(BUTTON, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING); 152 * 153 * // Configure an LED output pin 154 * GPIO_setConfig(LED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); 155 * } 156 * @endcode 157 * 158 * ### GPIO Driver Configuration # 159 * 160 * In order to use the GPIO APIs, the application is required 161 * to provide 3 structures in the ti_drivers_config.c file: 162 * 1. An array of @ref GPIO_PinConfig elements that defines the 163 * initial configuration of each pin used by the application. A 164 * pin is referenced in the application by its corresponding index in this 165 * array. The pin type (that is, INPUT/OUTPUT), its initial state (that is 166 * OUTPUT_HIGH or LOW), interrupt behavior (RISING/FALLING edge, etc.), and 167 * device specific pin identification are configured in each element 168 * of this array (see @ref GPIO_PinConfigSettings). 169 * Below is an MSP432 device specific example of the GPIO_PinConfig array: 170 * @code 171 * // 172 * // Array of Pin configurations 173 * // 174 * GPIO_PinConfig gpioPinConfigs[] = { 175 * // Input pins 176 * // MSP_EXP432P401R_GPIO_S1 177 * GPIOMSP432_P1_1 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING, 178 * // MSP_EXP432P401R_GPIO_S2 179 * GPIOMSP432_P1_4 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING, 180 * 181 * // Output pins 182 * // MSP_EXP432P401R_GPIO_LED1 183 * GPIOMSP432_P1_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, 184 * // MSP_EXP432P401R_GPIO_LED_RED 185 * GPIOMSP432_P2_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, 186 * }; 187 * @endcode 188 * 189 * 2. An array of @ref GPIO_CallbackFxn elements that is used to store 190 * callback function pointers for GPIO pins configured with interrupts. 191 * The indexes for these array elements correspond to the pins defined 192 * in the GPIO_pinConfig array. These function pointers can be defined 193 * statically by referencing the callback function name in the array 194 * element, or dynamically, by setting the array element to NULL and using 195 * GPIO_setCallback() at runtime to plug the callback entry. 196 * Pins not used for interrupts can be omitted from the callback array to 197 * reduce memory usage (if they are placed at the end of GPIO_pinConfig 198 * array). The callback function syntax should match the following: 199 * @code 200 * void (*GPIO_CallbackFxn)(uint_least8_t index); 201 * @endcode 202 * The index parameter is the same index that was passed to 203 * GPIO_setCallback(). This allows the same callback function to be used 204 * for multiple GPIO interrupts, by using the index to identify the GPIO 205 * that caused the interrupt. 206 * @remark Callback functions are called in the context of an interrupt 207 * service routine and should be designed accordingly. 208 * 209 * When an interrupt is triggered, the interrupt status of all 210 * (interrupt enabled) pins on a port will be read, cleared, and the 211 * respective callbacks will be executed. Callbacks will be called in order 212 * from least significant bit to most significant bit. 213 * Below is an MSP432 device specific example of the GPIO_CallbackFxn array: 214 * @code 215 * // 216 * // Array of callback function pointers 217 * // 218 * GPIO_CallbackFxn gpioCallbackFunctions[] = { 219 * // MSP_EXP432P401R_GPIO_S1 220 * NULL, 221 * // MSP_EXP432P401R_GPIO_S2 222 * NULL 223 * }; 224 * @endcode 225 * 226 * 3. A device specific GPIOxxx_Config structure that tells the GPIO 227 * driver where the two aforementioned arrays are and the number of elements 228 * in each. The interrupt priority of all pins configured to generate 229 * interrupts is also specified here. Values for the interrupt priority are 230 * device-specific. You should be well-acquainted with the interrupt 231 * controller used in your device before setting this parameter to a 232 * non-default value. The sentinel value of (~0) (the default value) is 233 * used to indicate that the lowest possible priority should be used. 234 * Below is an MSP432 device specific example of a GPIOxxx_Config 235 * structure: 236 * @code 237 * // 238 * // MSP432 specific GPIOxxx_Config structure 239 * // 240 * const GPIOMSP432_Config GPIOMSP432_config = { 241 * .pinConfigs = (GPIO_PinConfig *)gpioPinConfigs, 242 * .callbacks = (GPIO_CallbackFxn *)gpioCallbackFunctions, 243 * .numberOfPinConfigs = sizeof(gpioPinConfigs)/sizeof(GPIO_PinConfig), 244 * .numberOfCallbacks = sizeof(gpioCallbackFunctions)/sizeof(GPIO_CallbackFxn), 245 * .intPriority = (~0) 246 * }; 247 * @endcode 248 * 249 * ### Initializing the GPIO Driver # 250 * 251 * GPIO_init() must be called before any other GPIO APIs. This function 252 * configures each GPIO pin in the user-provided @ref GPIO_PinConfig 253 * array according to the defined settings. The user can also reconfigure 254 * a pin dynamically after GPIO_init() is called by using the 255 * GPIO_setConfig(), and GPIO_setCallback() APIs. 256 * 257 * # Implementation # 258 * 259 * Unlike most other TI-RTOS drivers, the GPIO driver has no generic function 260 * table with pointers to device-specific API implementations. All the generic 261 * GPIO APIs are implemented by the device-specific GPIO driver module. 262 * Additionally, there is no notion of an instance 'handle' with the GPIO 263 * driver. 264 * 265 * GPIO pins are referenced by their numeric index in the GPIO_PinConfig 266 * array. This design approach was used to enhance runtime and memory 267 * efficiency. 268 * 269 ****************************************************************************** 270 */ 271 272 #ifndef ti_drivers_GPIO__include 273 #define ti_drivers_GPIO__include 274 275 #include <stdint.h> 276 277 #ifdef __cplusplus 278 extern "C" { 279 #endif 280 281 /** 282 * @name GPIO_STATUS_* macros are general status codes returned by GPIO driver APIs. 283 * @{ 284 */ 285 286 /*! 287 * @brief Common GPIO status code reservation offset. 288 * 289 * GPIO driver implementations should offset status codes with 290 * GPIO_STATUS_RESERVED growing negatively. 291 * 292 * Example implementation specific status codes: 293 * @code 294 * #define GPIOTXYZ_STATUS_ERROR1 GPIO_STATUS_RESERVED - 1 295 * #define GPIOTXYZ_STATUS_ERROR0 GPIO_STATUS_RESERVED - 0 296 * #define GPIOTXYZ_STATUS_ERROR2 GPIO_STATUS_RESERVED - 2 297 * @endcode 298 */ 299 #define GPIO_STATUS_RESERVED (-32) 300 301 /*! 302 * @brief Successful status code returned by GPI_setConfig(). 303 * 304 * GPI_setConfig() returns GPIO_STATUS_SUCCESS if the API was executed 305 * successfully. 306 */ 307 #define GPIO_STATUS_SUCCESS (0) 308 309 /*! 310 * @brief Generic error status code returned by GPI_setConfig(). 311 * 312 * GPI_setConfig() returns GPIO_STATUS_ERROR if the API was not executed 313 * successfully. 314 */ 315 #define GPIO_STATUS_ERROR (-1) 316 /** @}*/ 317 318 /*! 319 * @brief GPIO pin configuration settings 320 * 321 * The upper 16 bits of the 32 bit PinConfig is reserved 322 * for pin configuration settings. 323 * 324 * The lower 16 bits are reserved for device-specific 325 * port/pin identifications 326 */ 327 typedef uint32_t GPIO_PinConfig; 328 329 /*! 330 * @cond NODOC 331 * Internally used configuration bit access macros. 332 */ 333 #define GPIO_CFG_IO_MASK 0x00ff0000 334 #define GPIO_CFG_IO_LSB 16 335 #define GPIO_CFG_OUT_TYPE_MASK 0x00060000 336 #define GPIO_CFG_OUT_TYPE_LSB 17 337 #define GPIO_CFG_IN_TYPE_MASK 0x00060000 338 #define GPIO_CFG_IN_TYPE_LSB 17 339 #define GPIO_CFG_OUT_STRENGTH_MASK 0x00f00000 340 #define GPIO_CFG_OUT_STRENGTH_LSB 20 341 #define GPIO_CFG_INT_MASK 0x07000000 342 #define GPIO_CFG_INT_LSB 24 343 #define GPIO_CFG_OUT_BIT 19 344 /*! @endcond */ 345 346 /*! 347 * \defgroup GPIO_PinConfigSettings Macros used to configure GPIO pins 348 * @{ 349 */ 350 /** @name GPIO_PinConfig output pin configuration macros 351 * @{ 352 */ 353 #define GPIO_CFG_OUTPUT (((uint32_t) 0) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Pin is an output. */ 354 #define GPIO_CFG_OUT_STD (((uint32_t) 0) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Output pin is actively driven high and low */ 355 #define GPIO_CFG_OUT_OD_NOPULL (((uint32_t) 2) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Output pin is Open Drain */ 356 #define GPIO_CFG_OUT_OD_PU (((uint32_t) 4) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Output pin is Open Drain w/ pull up */ 357 #define GPIO_CFG_OUT_OD_PD (((uint32_t) 6) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Output pin is Open Drain w/ pull dn */ 358 359 #define GPIO_CFG_OUT_STR_LOW (((uint32_t) 0) << GPIO_CFG_OUT_STRENGTH_LSB) /*!< @hideinitializer Set output pin strength to low */ 360 #define GPIO_CFG_OUT_STR_MED (((uint32_t) 1) << GPIO_CFG_OUT_STRENGTH_LSB) /*!< @hideinitializer Set output pin strength to medium */ 361 #define GPIO_CFG_OUT_STR_HIGH (((uint32_t) 2) << GPIO_CFG_OUT_STRENGTH_LSB) /*!< @hideinitializer Set output pin strength to high */ 362 363 #define GPIO_CFG_OUT_HIGH (((uint32_t) 1) << GPIO_CFG_OUT_BIT) /*!< @hideinitializer Set pin's output to 1. */ 364 #define GPIO_CFG_OUT_LOW (((uint32_t) 0) << GPIO_CFG_OUT_BIT) /*!< @hideinitializer Set pin's output to 0. */ 365 /** @} */ 366 367 /** @name GPIO_PinConfig input pin configuration macros 368 * @{ 369 */ 370 #define GPIO_CFG_INPUT (((uint32_t) 1) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Pin is an input. */ 371 #define GPIO_CFG_IN_NOPULL (((uint32_t) 1) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Input pin with no internal PU/PD */ 372 #define GPIO_CFG_IN_PU (((uint32_t) 3) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Input pin with internal PU */ 373 #define GPIO_CFG_IN_PD (((uint32_t) 5) << GPIO_CFG_IO_LSB) /*!< @hideinitializer Input pin with internal PD */ 374 /** @} */ 375 376 /** @name GPIO_PinConfig interrupt configuration macros 377 * @{ 378 */ 379 #define GPIO_CFG_IN_INT_NONE (((uint32_t) 0) << GPIO_CFG_INT_LSB) /*!< @hideinitializer No Interrupt */ 380 #define GPIO_CFG_IN_INT_FALLING (((uint32_t) 1) << GPIO_CFG_INT_LSB) /*!< @hideinitializer Interrupt on falling edge */ 381 #define GPIO_CFG_IN_INT_RISING (((uint32_t) 2) << GPIO_CFG_INT_LSB) /*!< @hideinitializer Interrupt on rising edge */ 382 #define GPIO_CFG_IN_INT_BOTH_EDGES (((uint32_t) 3) << GPIO_CFG_INT_LSB) /*!< @hideinitializer Interrupt on both edges */ 383 #define GPIO_CFG_IN_INT_LOW (((uint32_t) 4) << GPIO_CFG_INT_LSB) /*!< @hideinitializer Interrupt on low level */ 384 #define GPIO_CFG_IN_INT_HIGH (((uint32_t) 5) << GPIO_CFG_INT_LSB) /*!< @hideinitializer Interrupt on high level */ 385 /** @} */ 386 387 /** @name Special GPIO_PinConfig configuration macros 388 * @{ 389 */ 390 391 /*! 392 * @brief 'Or' in this @ref GPIO_PinConfig definition to inform GPIO_setConfig() 393 * to only configure the interrupt attributes of a GPIO input pin. 394 */ 395 #define GPIO_CFG_IN_INT_ONLY (((uint32_t) 1) << 27) /*!< @hideinitializer configure interrupt only */ 396 397 /*! 398 * @brief Use this @ref GPIO_PinConfig definition to inform GPIO_init() 399 * NOT to configure the corresponding pin 400 */ 401 #define GPIO_DO_NOT_CONFIG 0x40000000 /*!< @hideinitializer Do not configure this Pin */ 402 403 /** @} */ 404 /** @} end of GPIO_PinConfigSettings group */ 405 406 /*! 407 * @brief GPIO callback function type 408 * 409 * @param index GPIO index. This is the same index that 410 * was passed to GPIO_setCallback(). This allows 411 * you to use the same callback function for multiple 412 * GPIO interrupts, by using the index to identify 413 * the GPIO that caused the interrupt. 414 */ 415 typedef void (*GPIO_CallbackFxn)(uint_least8_t index); 416 417 /*! 418 * @brief Clear a GPIO pin interrupt flag 419 * 420 * Clears the GPIO interrupt for the specified index. 421 * 422 * Note: It is not necessary to call this API within a 423 * callback assigned to a pin. 424 * 425 * @param index GPIO index 426 */ 427 extern void GPIO_clearInt(uint_least8_t index); 428 429 /*! 430 * @brief Disable a GPIO pin interrupt 431 * 432 * Disables interrupts for the specified GPIO index. 433 * 434 * @param index GPIO index 435 */ 436 extern void GPIO_disableInt(uint_least8_t index); 437 438 /*! 439 * @brief Enable a GPIO pin interrupt 440 * 441 * Enables GPIO interrupts for the selected index to occur. 442 * 443 * Note: Prior to enabling a GPIO pin interrupt, make sure 444 * that a corresponding callback function has been provided. 445 * Use the GPIO_setCallback() API for this purpose at runtime. 446 * Alternatively, the callback function can be statically 447 * configured in the GPIO_CallbackFxn array provided. 448 * 449 * @param index GPIO index 450 */ 451 extern void GPIO_enableInt(uint_least8_t index); 452 453 /*! 454 * @brief Get the current configuration for a gpio pin 455 * 456 * The pin configuration is provided in the static GPIO_PinConfig array, 457 * but can be changed with GPIO_setConfig(). GPIO_getConfig() gets the 458 * current pin configuration. 459 * 460 * @param index GPIO index 461 * @param pinConfig Location to store device specific pin 462 * configuration settings 463 */ 464 extern void GPIO_getConfig(uint_least8_t index, GPIO_PinConfig *pinConfig); 465 466 /*! 467 * @brief Initializes the GPIO module 468 * 469 * The pins defined in the application-provided *GPIOXXX_config* structure 470 * are initialized accordingly. 471 * 472 * @pre The GPIO_config structure must exist and be persistent before this 473 * function can be called. This function must also be called before 474 * any other GPIO driver APIs. 475 */ 476 extern void GPIO_init(); 477 478 /*! 479 * @brief Reads the value of a GPIO pin 480 * 481 * The value returned will either be zero or one depending on the 482 * state of the pin. 483 * 484 * @param index GPIO index 485 * 486 * @return 0 or 1, depending on the state of the pin. 487 */ 488 extern uint_fast8_t GPIO_read(uint_least8_t index); 489 490 /*! 491 * @brief Bind a callback function to a GPIO pin interrupt 492 * 493 * Associate a callback function with a particular GPIO pin interrupt. 494 * 495 * Callbacks can be changed at any time, making it easy to switch between 496 * efficient, state-specific interrupt handlers. 497 * 498 * Note: The callback function is called within the context of an interrupt 499 * handler. 500 * 501 * Note: This API does not enable the GPIO pin interrupt. 502 * Use GPIO_enableInt() and GPIO_disableInt() to enable 503 * and disable the pin interrupt as necessary. 504 * 505 * Note: it is not necessary to call GPIO_clearInt() within a callback. 506 * That operation is performed internally before the callback is invoked. 507 * 508 * @param index GPIO index 509 * @param callback address of the callback function 510 */ 511 extern void GPIO_setCallback(uint_least8_t index, GPIO_CallbackFxn callback); 512 513 /*! 514 * @brief Configure the gpio pin 515 * 516 * Dynamically configure a gpio pin to a device specific setting. 517 * For many applications, the pin configurations provided in the static 518 * GPIO_PinConfig array is sufficient. 519 * 520 * For input pins with interrupt configurations, a corresponding interrupt 521 * object will be created as needed. 522 * 523 * @param index GPIO index 524 * @param pinConfig device specific pin configuration settings 525 */ 526 extern int_fast16_t GPIO_setConfig(uint_least8_t index, 527 GPIO_PinConfig pinConfig); 528 529 /*! 530 * @brief Toggles the current state of a GPIO 531 * 532 * @param index GPIO index 533 */ 534 extern void GPIO_toggle(uint_least8_t index); 535 536 /*! 537 * @brief Writes the value to a GPIO pin 538 * 539 * @param index GPIO index 540 * @param value must be either 0 or 1 541 */ 542 extern void GPIO_write(uint_least8_t index, unsigned int value); 543 544 #ifdef __cplusplus 545 } 546 #endif 547 548 #endif /* ti_drivers_GPIO__include */ 549