//***************************************************************************** // // am_hal_gpio.h //! @file //! //! @brief Functions for accessing and configuring the GPIO module. //! //! @addtogroup gpio3p GPIO //! @ingroup apollo3phal //! @{ // //***************************************************************************** //***************************************************************************** // // Copyright (c) 2020, Ambiq Micro // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the name of the copyright holder nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // Third party software included in this distribution is subject to the // additional license terms as defined in the /docs/licenses directory. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 2.4.2 of the AmbiqSuite Development Package. // //***************************************************************************** #ifndef AM_HAL_GPIO_H #define AM_HAL_GPIO_H 1 #ifdef __cplusplus extern "C" { #endif // // Designate this peripheral. // #define AM_APOLLO3_GPIO 1 // // Maximum number of GPIOs on this device // #define AM_HAL_GPIO_MAX_PADS (74) #define AM_HAL_GPIO_NUMWORDS ((AM_HAL_GPIO_MAX_PADS + 31) / 32) // //! Macros to assist with defining a GPIO mask given a GPIO number. //! //! IMPORTANT: AM_HAL_GPIO_BIT(n) is DEPRECATED and is replaced with //! AM_HAL_GPIO_MASKBIT(). // #define AM_HAL_GPIO_BIT(n) DEPRECATED_USE_AM_HAL_GPIO_MASKBIT // Force a compile error if used //! //! The following macros ensure forward compatibility with future SDK releases. //! They should be used, in lieu of AM_HAL_GPIO_BIT(), when creating bitmasks //! for GPIO interrupts. //! AM_HAL_GPIO_MASKCREATE() //! AM_HAL_GPIO_MASKBIT() //! #define AM_HAL_GPIO_MASKCREATE(sMaskNm) \ am_hal_gpio_mask_t sMaskNm; \ am_hal_gpio_mask_t *p##sMaskNm = &sMaskNm; \ sMaskNm.U.Msk[0] = sMaskNm.U.Msk[1] = sMaskNm.U.Msk[2] = 0; //! AM_HAL_GPIO_MASKCREATE() should be used before AM_HAL_GPIO_MASKBIT() to //! ensure forward compatibility. In future releases it will allocate and //! initialize a bitmask structure used in the various GPIO interrupt functions. //! // #define AM_HAL_GPIO_MASKBIT(psMaskNm, n) inline_function_below //! AM_HAL_GPIO_MASKBIT(psMaskNm, n) //! Implemented as an inline function below. //! Support macros for use with AM_HAL_GPIO_MASKBIT(). //! AM_HAL_GPIO_MASKCREATE() //! AM_HAL_GPIO_MASKCLR() //! //! To set a single bit based on a pin number in an existing bitmask structure. //! AM_HAL_GPIO_MASKBIT(pGpioIntMask, n) //! where n is the desired GPIO bit number. //! Note - this usage is analogous to the deprecated AM_HAL_GPIO_BIT(n). //! #define AM_HAL_GPIO_MASKCLR(psMaskNm) ( psMaskNm->U.Msk[0] = psMaskNm->U.Msk[1] = psMaskNm->U.Msk[2] = 0 ) //! AM_HAL_GPIO_MASKCLR() //! Clear an existing GpioIntMask bitmask structure. //! Note that AM_HAL_GPIO_MASKCREATE() clears the bitmask struct on creation. //! IMPORTANT - The AM_HAL_GPIO_MASKCLR() macro does not operate on any hardware //! or register. It is used for initializing/clearing the memory allocated for //! the bitmask structure. //! //! // Usage example for any Apollo device: //! // Create a GPIO interrupt bitmask structure named GpioIntMask, initialize //! // that structure, and create a ptr to that structure named pGpioIntMask. //! // Then use that structure to pass a bitmask to the interrupt function. //! AM_HAL_GPIO_MASKCREATE(GpioIntMask); //! am_hal_gpio_interrupt_clear(AM_HAL_GPIO_MASKBIT(pGpioIntMask)); //! //***************************************************************************** //! //! Structure for defining bitmasks used in the interrupt functions. //! //***************************************************************************** typedef struct { union { volatile uint32_t Msk[AM_HAL_GPIO_NUMWORDS]; struct { volatile uint32_t b0: 1; volatile uint32_t b1: 1; volatile uint32_t b2: 1; volatile uint32_t b3: 1; volatile uint32_t b4: 1; volatile uint32_t b5: 1; volatile uint32_t b6: 1; volatile uint32_t b7: 1; volatile uint32_t b8: 1; volatile uint32_t b9: 1; volatile uint32_t b10: 1; volatile uint32_t b11: 1; volatile uint32_t b12: 1; volatile uint32_t b13: 1; volatile uint32_t b14: 1; volatile uint32_t b15: 1; volatile uint32_t b16: 1; volatile uint32_t b17: 1; volatile uint32_t b18: 1; volatile uint32_t b19: 1; volatile uint32_t b20: 1; volatile uint32_t b21: 1; volatile uint32_t b22: 1; volatile uint32_t b23: 1; volatile uint32_t b24: 1; volatile uint32_t b25: 1; volatile uint32_t b26: 1; volatile uint32_t b27: 1; volatile uint32_t b28: 1; volatile uint32_t b29: 1; volatile uint32_t b30: 1; volatile uint32_t b31: 1; volatile uint32_t b32: 1; volatile uint32_t b33: 1; volatile uint32_t b34: 1; volatile uint32_t b35: 1; volatile uint32_t b36: 1; volatile uint32_t b37: 1; volatile uint32_t b38: 1; volatile uint32_t b39: 1; volatile uint32_t b40: 1; volatile uint32_t b41: 1; volatile uint32_t b42: 1; volatile uint32_t b43: 1; volatile uint32_t b44: 1; volatile uint32_t b45: 1; volatile uint32_t b46: 1; volatile uint32_t b47: 1; volatile uint32_t b48: 1; volatile uint32_t b49: 1; volatile uint32_t b50: 1; volatile uint32_t b51: 1; volatile uint32_t b52: 1; volatile uint32_t b53: 1; volatile uint32_t b54: 1; volatile uint32_t b55: 1; volatile uint32_t b56: 1; volatile uint32_t b57: 1; volatile uint32_t b58: 1; volatile uint32_t b59: 1; volatile uint32_t b60: 1; volatile uint32_t b61: 1; volatile uint32_t b62: 1; volatile uint32_t b63: 1; volatile uint32_t b64: 1; volatile uint32_t b65: 1; volatile uint32_t b66: 1; volatile uint32_t b67: 1; volatile uint32_t b68: 1; volatile uint32_t b69: 1; volatile uint32_t b70: 1; volatile uint32_t b71: 1; volatile uint32_t b72: 1; volatile uint32_t b73: 1; volatile uint32_t brsvd: 22; // Pad out to the next full word } Msk_b; } U; } am_hal_gpio_mask_t; //***************************************************************************** //! //! AM_HAL_GPIO_MASKBIT() //! //***************************************************************************** // // AM_HAL_GPIO_MASKBIT(psMaskNm, n) // // Entry: // psMaskNm is a pointer to the structure type, am_hal_gpio_mask_t. // n is the desired bitnumber. // // Returns ptr to the bit structure. // // Since the ptr is required as a return value, a macro does not work. // Therefore an inline function is used. // static inline am_hal_gpio_mask_t* AM_HAL_GPIO_MASKBIT(am_hal_gpio_mask_t*psMaskNm, uint32_t n) { psMaskNm->U.Msk[n / 32] = (1 << (n % 32)); return psMaskNm; } //***************************************************************************** //! //! Read types for am_hal_gpio_state_read(). //! //***************************************************************************** typedef enum { AM_HAL_GPIO_INPUT_READ, AM_HAL_GPIO_OUTPUT_READ, AM_HAL_GPIO_ENABLE_READ } am_hal_gpio_read_type_e; //***************************************************************************** //! //! Write types for am_hal_gpio_state_write(). //! //***************************************************************************** typedef enum { AM_HAL_GPIO_OUTPUT_CLEAR, AM_HAL_GPIO_OUTPUT_SET, AM_HAL_GPIO_OUTPUT_TOGGLE, AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE, AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE, AM_HAL_GPIO_OUTPUT_TRISTATE_TOGGLE } am_hal_gpio_write_type_e; //***************************************************************************** //! //! Types for ui32GpioCfg bitfields in am_hal_gpio_pinconfig(). //! //***************************************************************************** //! //! Power Switch configuration: am_hal_gpio_pincfg_t.ePowerSw enums //! typedef enum { AM_HAL_GPIO_PIN_POWERSW_NONE, AM_HAL_GPIO_PIN_POWERSW_VDD, AM_HAL_GPIO_PIN_POWERSW_VSS, AM_HAL_GPIO_PIN_POWERSW_INVALID, } am_hal_gpio_powersw_e; //! //! Pullup configuration: am_hal_gpio_pincfg_t.ePullup enums //! typedef enum { // //! Define pullup enums. //! The 1.5K - 24K pullup values are valid for select I2C enabled pads. //! For Apollo3 these pins are 0-1,5-6,8-9,25,27,39-40,42-43,48-49. //! The "weak" value is used for almost every other pad except pin 20. // AM_HAL_GPIO_PIN_PULLUP_NONE = 0x00, AM_HAL_GPIO_PIN_PULLUP_WEAK, AM_HAL_GPIO_PIN_PULLUP_1_5K, AM_HAL_GPIO_PIN_PULLUP_6K, AM_HAL_GPIO_PIN_PULLUP_12K, AM_HAL_GPIO_PIN_PULLUP_24K, AM_HAL_GPIO_PIN_PULLDOWN } am_hal_gpio_pullup_e; //! //! Pad Drive Strength configuration: am_hal_gpio_pincfg_t.eDriveStrength enums //! typedef enum { // //! DRIVESTRENGTH is a 2-bit field. //! bit0 maps to bit2 of a PADREG field. //! bit1 maps to bit0 of an ALTPADCFG field. // AM_HAL_GPIO_PIN_DRIVESTRENGTH_2MA = 0x0, AM_HAL_GPIO_PIN_DRIVESTRENGTH_4MA = 0x1, AM_HAL_GPIO_PIN_DRIVESTRENGTH_8MA = 0x2, AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA = 0x3 } am_hal_gpio_drivestrength_e; //! //! OUTCFG pad configuration: am_hal_gpio_pincfg_t.eGPOutcfg enums //! Applies only to GPIO configured pins. //! Ultimately maps to GPIOCFG.OUTCFG, bits [2:1]. //! typedef enum { AM_HAL_GPIO_PIN_OUTCFG_DISABLE = 0x0, AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL = 0x1, AM_HAL_GPIO_PIN_OUTCFG_OPENDRAIN = 0x2, AM_HAL_GPIO_PIN_OUTCFG_TRISTATE = 0x3 } am_hal_gpio_outcfg_e; //! //! GPIO input configuration: am_hal_gpio_pincfg_t.eGPInput enums //! Applies only to GPIO configured pins! //! Ultimately maps to PADREG.INPEN, bit1. //! typedef enum { AM_HAL_GPIO_PIN_INPUT_AUTO = 0x0, AM_HAL_GPIO_PIN_INPUT_NONE = 0x0, AM_HAL_GPIO_PIN_INPUT_ENABLE = 0x1 } am_hal_gpio_input_e; //! //! GPIO interrupt direction configuration: am_hal_gpio_pincfg_t.eIntDir enums //! Note: Setting INTDIR_NONE has the side-effect of disabling being able to //! read a pin - the pin will always read back as 0. //! typedef enum { // Bit1 of these values maps to GPIOCFG.INCFG (b0). // Bit0 of these values maps to GPIOCFG.INTD (b3). AM_HAL_GPIO_PIN_INTDIR_LO2HI = 0x0, AM_HAL_GPIO_PIN_INTDIR_HI2LO = 0x1, AM_HAL_GPIO_PIN_INTDIR_NONE = 0x2, AM_HAL_GPIO_PIN_INTDIR_BOTH = 0x3 } am_hal_gpio_intdir_e; //! //! am_hal_gpio_pincfg_t.eGPRdZero //! For GPIO configurations (funcsel=3), the pin value can be read or 0 can be //! forced as the read value. //! typedef enum { AM_HAL_GPIO_PIN_RDZERO_READPIN = 0x0, AM_HAL_GPIO_PIN_RDZERO_ZERO = 0x1 } am_hal_gpio_readen_e; //! //! nCE polarity configuration: am_hal_gpio_pincfg_t.eCEpol enums //! typedef enum { AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW = 0x0, AM_HAL_GPIO_PIN_CEPOL_ACTIVEHIGH = 0x1 } am_hal_gpio_cepol_e; // // Apollo3 usage of bits [7:6] of a PADREG field: // PULLUPs are available on pins: 0,1,5,6,8,9,25,27,39,40,42,43,48,49 // RESERVED on pins: 2,4,7,10-24,26,28-35,38,44-47 // VDD PWR on pins: 3, 36 (b7=0, b6=1) // VSS PWR on pins: 37,41 (b7=1, b6=0) // //! //! Define the am_hal_gpio_pinconfig() bitfield structure. //! uFuncSel a value of 0-7 corresponding to the FNCSEL field of PADREG. //! ePowerSw: Select pins can be set as a power source or sink. //! ePullup: Select pins can enable a pullup of varying values. //! eDriveStrength: Select pins can be set for varying drive strengths. //! eGPOutcfg: GPIO pin only, corresponds to GPIOCFG.OUTCFG field. //! eGPInput: GPIO pin only, corresponds to PADREG.INPEN. //! eGPRdZero: GPIO read zero. Corresponds to GPIOCFG.INCFG. //! eIntDir: Interrupt direction, l2h, h2l, both, none. //! eGPRdZero: Read the pin value, or always read the pin as zero. //! uIOMnum: nCE pin IOMnumber (0-5, or 6 for MSPI) //! nNCE: Selects the SPI channel (CE) number (0-3) //! eCEpol: CE polarity. //! typedef struct { uint32_t uFuncSel : 3; // [2:0] Function select (FUNCSEL) uint32_t ePowerSw : 2; // [4:3] Pin is a power switch source (VCC) or sink (VSS) uint32_t ePullup : 3; // [7:5] Pin will enable a pullup resistor uint32_t eDriveStrength : 2; // [9:8] Pad strength designator uint32_t eGPOutcfg : 2; // [11:10] OUTCFG (GPIO config only) uint32_t eGPInput : 1; // [12:12] GPIO Input (GPIO config only) uint32_t eIntDir : 2; // [14:13] Interrupt direction uint32_t eGPRdZero : 1; // [15:15] GPIO read as zero // // The following descriptors designate the chip enable features of the // pin being configured. If not a CE, these descriptors are ignored. // uIOMnum is 0-5 for the IOMs, or 0-2 for MSPI. // uint32_t bIomMSPIn : 1; // [16:16] 1 if CE is IOM, 0 if MSPI uint32_t uIOMnum : 3; // [19:17] IOM number (0-5) or MSPI (0-2) uint32_t uNCE : 2; // [21:20] NCE number (0-3). uint32_t eCEpol : 1; // [22:22] NCE polarity. uint32_t uRsvd23 : 9; // [31:23] } am_hal_gpio_pincfg_t; //#define IOMNUM_MSPI 6 //#define IOMNUM_MAX IOMNUM_MSPI // // Define shift and width values for the above bitfields. // - C bitfields do not provide shift, width, or mask values. // - Shift values are generally compiler specific. However for IAR, Keil, and // GCC, the bitfields are all exactly as defined in the above structure. // - These defines should be used sparingly. // #define UFUNCSEL_S 0 #define EPOWERSW_S 3 #define EPULLUP_S 5 #define EDRVSTR_S 8 #define EGPOUTCFG_S 10 #define EGPINPUT_S 12 #define EINTDIR_S 13 #define UIOMNUM_S 16 #define UNCE_S 19 #define ECEPOL_S 21 #define UFUNCSEL_W 3 #define EPOWERSW_W 2 #define EPULLUP_W 3 #define EDRVSTR_W 2 #define EGPOUTCFG_W 2 #define EGPINPUT_W 1 #define EINTDIR_W 2 #define UIOMNUM_W 3 #define UNCE_W 2 #define ECEPOL_W 1 //! //! Define GPIO error codes that are returned by am_hal_gpio_pinconfig(). //! enum am_hal_gpio_pincfgerr { AM_HAL_GPIO_ERR_PULLUP = (AM_HAL_STATUS_MODULE_SPECIFIC_START + 0x100), AM_HAL_GPIO_ERR_PULLDOWN, AM_HAL_GPIO_ERR_PWRSW, AM_HAL_GPIO_ERR_INVCE, AM_HAL_GPIO_ERR_INVCEPIN, AM_HAL_GPIO_ERR_PULLUPENUM }; //***************************************************************************** // // Globals // //***************************************************************************** //***************************************************************************** // Define some common GPIO pin configurations. //***************************************************************************** //! Basics extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_DISABLE; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_TRISTATE; //! Input variations extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT; //! Input with various pullups (weak, 1.5K, 6K, 12K, 24K) extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_1_5; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_6; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_12; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_24; //! Output variations extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_4; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_8; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_12; extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_WITH_READ; //***************************************************************************** // // Function pointer type for GPIO interrupt handlers. // //***************************************************************************** typedef void (*am_hal_gpio_handler_t)(void); typedef void (*am_hal_gpio_handler_adv_t)(void *); //***************************************************************************** // //! @brief Configure an Apollo3 pin. //! //! @param ui32Pin - pin number to be configured. //! @param ui32GpioCfg - Contains multiple descriptor fields. //! //! This function configures a pin according to the descriptor parameters as //! passed in sPinCfg. All parameters are validated with regard to each //! other and according to the requested function. Once the parameters and //! settings have been confirmed, the pin is configured accordingly. //! //! @return Status. // //***************************************************************************** extern uint32_t am_hal_gpio_pinconfig(uint32_t ui32Pin, am_hal_gpio_pincfg_t sPincfg); //***************************************************************************** // //! @brief Configure specified pins for FAST GPIO operation. //! //! @param psPinMask - a mask specifying up to 8 pins to be configured and //! used for FAST GPIO (only bits 0-73 are valid). //! @param bfGpioCfg - The GPIO configuration (same as am_hal_gpio_pinconfig()). //! All of the pins specified by psPinMask will be set to this //! configuration. //! @param ui32Masks - If NULL, not used. Otherwise if provided, an array to //! receive two 32-bit values, per pin, of the SET and CLEAR //! masks that can be used for the BBSETCLEAR register. //! The two 32-bit values will be placed at incremental indexes. //! For example, say pin numbers 5 and 19 are indicated in the //! mask, and an array pointer is provided in ui32Masks. This //! array must be allocated by the caller to be at least 4 wds. //! ui32Masks[0] = the set mask used for pin 5. //! ui32Masks[1] = the clear mask used for pin 5. //! ui32Masks[2] = the set mask used for pin 19. //! ui32Masks[3] = the clear mask used for pin 19. //! //! @return Status. //! //! Fast GPIO helper macros: //! am_hal_gpio_fastgpio_set(n) - Sets the value for pin number 'n'. //! am_hal_gpio_fastgpio_clr(n) - Clear the value for pin number 'n'. //! //! am_hal_gpio_fastgpio_enable(n) - Enable Fast GPIO on pin 'n'. //! am_hal_gpio_fastgpio_disable(n) - Disable Fast GPIO on pin 'n'. //! //! Note - The enable and disable macros assume the pin has already been //! configured. Once disabled, the state of the pin will revert to the //! state of the normal GPIO configuration for that pin. //! //! NOTES on pin configuration: //! - To avoid glitches on the pin, it is strongly recommended that before // calling am_hal_gpio_fast_pinconfig() that am_hal_gpio_fastgpio_disable() //! first be called to make sure that Fast GPIO is disabled before config. //! - If the state of the pin is important, preset the value of the pin to the //! desired value BEFORE calling am_hal_gpio_fast_pinconfig(). The set and //! clear macros shown above can be used for this purpose. //! //! NOTES on general use of Fast GPIO: //! Fast GPIO input or output will not work if the pin is configured as //! tristate. The overloaded OUTPUT ENABLE control is used for enabling both //! modes, so Apollo3 logic specifically disallows Fast GPIO input or output //! when the pin is configured for tristate mode. //! Fast GPIO input can be used for pushpull, opendrain, or disable modes. //! //! Fast GPIO pin groupings: //! The FaST GPIO pins are grouped across a matrix of pins. Each //! row of pins is controlled by a single data bit. //! //! Referring to the below chart: //! If pin 35 were configured for Fast GPIO output, it would be set //! when bit3 of BBSETCLEAR.SET was written with a 1. //! It would be cleared when bit3 of BBSETCLEAR.CLEAR was written with 1. //! //! Note that if all the pins in a row were configured for Fast GPIO output, //! all the pins would respond to set/clear. //! //! Input works in a similar fashion. //! //! BIT PIN controlled //! --- --------------------------------------- //! 0 0 8 16 24 32 40 48 56 64 72 //! 1 1 9 17 25 33 41 49 57 65 73 //! 2 2 10 18 26 34 42 50 58 66 //! 3 3 11 19 27 35 43 51 59 67 //! 4 4 12 20 28 36 44 52 60 68 //! 5 5 13 21 29 37 45 53 61 69 //! 6 6 14 22 30 38 46 54 62 70 //! 7 7 15 23 31 39 47 55 63 71 //! // //***************************************************************************** extern uint32_t am_hal_gpio_fast_pinconfig(am_hal_gpio_mask_t *psPinMask, am_hal_gpio_pincfg_t bfGpioCfg, uint32_t ui32Masks[]); //***************************************************************************** // //! @brief Read GPIO. //! //! @param ui32Pin - pin number to be read. //! @param eReadType - State type to read. One of: //! AM_HAL_GPIO_INPUT_READ //! AM_HAL_GPIO_OUTPUT_READ //! AM_HAL_GPIO_ENABLE_READ //! //! This function reads a pin state as given by eReadType. //! //! @return Status. // //***************************************************************************** extern uint32_t am_hal_gpio_state_read(uint32_t ui32Pin, am_hal_gpio_read_type_e eReadType, uint32_t *pu32RetVal); //***************************************************************************** // //! @brief Write GPIO. //! //! @param ui32Pin - pin number to be read. //! //! @param eWriteType - State type to write. One of: //! AM_HAL_GPIO_OUTPUT_SET - Write a one to a GPIO. //! AM_HAL_GPIO_OUTPUT_CLEAR - Write a zero to a GPIO. //! AM_HAL_GPIO_OUTPUT_TOGGLE - Toggle the GPIO value. //! The following two apply when output is set for TriState (OUTCFG==3). //! AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE - Enable a tri-state GPIO. //! AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE - Disable a tri-state GPIO. //! //! This function writes a GPIO value. //! //! @return Status. //! Fails if the pad is not configured for GPIO (PADFNCSEL != 3). // //***************************************************************************** extern uint32_t am_hal_gpio_state_write(uint32_t ui32Pin, am_hal_gpio_write_type_e eWriteType); //***************************************************************************** // //! @brief Enable GPIO interrupts. //! //! @param pGpioIntMask - Mask of GPIO interrupts to enable. //! Only bits 0-73 are valid in the mask. //! //! @return Status. //! Fails if any bit above bit73 is set in pGpioIntMask. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_enable(am_hal_gpio_mask_t *pGpioIntMask); //***************************************************************************** // //! @brief Disable GPIO interrupts. //! //! @param pGpioIntMask - Mask of GPIO interrupts to disable. //! Only bits 0-73 are valid in the mask. //! //! @return Status. //! Fails if any bit above bit73 is set in pGpioIntMask. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_disable(am_hal_gpio_mask_t *pGpioIntMask); //***************************************************************************** // //! @brief Clear GPIO interrupts. //! //! @param pGpioIntMask - Mask of GPIO interrupts to be cleared. //! Only bits 0-73 are valid in the mask. //! //! @return Status. //! Fails if any bit above bit73 is set in pGpioIntMask. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_clear(am_hal_gpio_mask_t *pGpioIntMask); //***************************************************************************** // //! @brief Get GPIO interrupt status. //! //! @param bEnabledOnly - Return status only for currently enabled interrupts. //! //! @param pGpioIntMask - Bitmask array to return a bitmask of the status //! of the interrupts. //! //! @return Status. //! Fails if pGpioIntMask is NULL. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_status_get(bool bEnabledOnly, am_hal_gpio_mask_t *pGpioIntMask); //***************************************************************************** // //! @brief GPIO interrupt service routine registration. //! //! @param ui32GPIONumber - GPIO number (0-73) to be registered. //! //! @param pfnHandler - Function pointer to the callback. //! //! @return Status. //! Fails if pfnHandler is NULL or ui32GPIONumber > 73. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_register(uint32_t ui32GPIONumber, am_hal_gpio_handler_t pfnHandler); //***************************************************************************** // //! @brief Advanced GPIO interrupt service routine registration. //! //! @param ui32GPIONumber - GPIO number (0-73) to be registered. //! //! @param pfnHandler - Function pointer to the callback. //! //! @param pCtxt - context for the callback. //! //! @return Status. //! Fails if pfnHandler is NULL or ui32GPIONumber > 73. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_register_adv(uint32_t ui32GPIONumber, am_hal_gpio_handler_adv_t pfnHandler, void *pCtxt); //***************************************************************************** // // GPIO interrupt service routine. //! @brief GPIO interrupt service routine registration. //! //! @param pGpioIntMask - Mask of the interrupt(s) to be serviced. This mask is //! typically obtained via a call to am_hal_gpio_interrupt_status_get(). //! //! The intended use is that the application first registers a handler for a //! particular GPIO via am_hal_gpio_interrupt_register(), and to supply the //! main ISR, am_gpio_isr(). //! //! On a GPIO interrupt, am_gpio_isr() calls am_hal_gpio_interrupt_status_get() //! and provides the return value to this function. //! //! In the event that multiple GPIO interrupts are active, the corresponding //! interrupt handlers will be called in numerical order by GPIO number //! starting with the lowest GPIO number. //! //! @return Status. //! AM_HAL_STATUS_INVALID_OPERATION if no handler had been registered //! for any of the GPIOs that caused the interrupt. //! AM_HAL_STATUS_OUT_OF_RANGE if any bit above bit73 is set. //! AM_HAL_STATUS_FAIL if pGpioIntMask is 0. //! AM_HAL_STATUS_SUCCESS otherwise. // //***************************************************************************** extern uint32_t am_hal_gpio_interrupt_service(am_hal_gpio_mask_t *pGpioIntMask); //***************************************************************************** // //! @brief Macros to read GPIO values in an optimized manner. //! //! @param n - The GPIO number to be read. //! //! In almost all cases, it is reasonable to use am_hal_gpio_state_read() to //! read GPIO values with all of the inherent error checking, critical //! sectioning, and general safety. //! //! However, occasionally there is a need to read a GPIO value in an optimized //! manner. These 3 macros will accomplish that. Each macro will return a //! value of 1 or 0. //! //! Note that the macros are named as lower-case counterparts to the //! enumerations for the am_hal_gpio_state_read() function. That is: //! //! AM_HAL_GPIO_INPUT_READ -> am_hal_gpio_input_read(n) //! AM_HAL_GPIO_OUTPUT_READ -> am_hal_gpio_output_read(n) //! AM_HAL_GPIO_ENABLE_READ -> am_hal_gpio_enable_read(n) //! //! @return Each macro will return a 1 or 0 per the value of the requested GPIO. //! // //***************************************************************************** #define am_hal_gpio_input_read(n) ( \ (AM_REGVAL( (AM_REGADDR(GPIO, RDA) + (((uint32_t)(n) & 0x60) >> 3)) ) >> /* Read appropriate register */ \ ((uint32_t)(n) & 0x1F) ) & /* Shift by appropriate number of bits */ \ ((uint32_t)0x1) ) /* Mask out the LSB */ #define am_hal_gpio_output_read(n) ( \ (AM_REGVAL( (AM_REGADDR(GPIO, WTA) + (((uint32_t)(n) & 0x60) >> 3)) ) >> /* Read appropriate register */ \ ((uint32_t)(n) & 0x1F) ) & /* Shift by appropriate number of bits */ \ ((uint32_t)0x1) ) /* Mask out the LSB */ #define am_hal_gpio_enable_read(n) ( \ (AM_REGVAL( (AM_REGADDR(GPIO, ENA) + (((uint32_t)(n) & 0x60) >> 3)) ) >> /* Read appropriate register */ \ ((uint32_t)(n) & 0x1F) ) & /* Shift by appropriate number of bits */ \ ((uint32_t)0x1) ) /* Mask out the LSB */ //***************************************************************************** // //! @brief Macros to write GPIO values in an optimized manner. //! //! @param n - The GPIO number to be written. //! //! In almost all cases, it is reasonable to use am_hal_gpio_state_write() to //! write GPIO values with all of the inherent error checking, critical //! sectioning, and general safety. //! //! However, occasionally there is a need to write a GPIO value in an optimized //! manner. These 3 macros will accomplish that. //! //! Note that the macros are named as lower-case counterparts to the //! enumerations for the am_hal_gpio_state_read() function. That is: //! //! AM_HAL_GPIO_OUTPUT_CLEAR -> am_hal_gpio_output_clear(n,v) //! AM_HAL_GPIO_OUTPUT_SET -> am_hal_gpio_output_set(n,v) //! AM_HAL_GPIO_OUTPUT_TOGGLE -> am_hal_gpio_output_toggle(n,v) //! AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE -> am_hal_gpio_output_tristate_disable(n,v) //! AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE -> am_hal_gpio_output_tristate_enable(n,v) //! AM_HAL_GPIO_OUTPUT_TRISTATE_TOGGLE -> am_hal_gpio_output_toggle(n,v) //! //! @return None. //! //***************************************************************************** // // Note - these macros use byte-oriented addressing. // #define am_hal_gpio_output_clear(n) \ ((*((volatile uint32_t *) \ ((AM_REGADDR(GPIO, WTCA) + (((uint32_t)(n) & 0x60) >> 3))))) = \ ((uint32_t) 0x1 << ((uint32_t)(n) % 32))) #define am_hal_gpio_output_set(n) \ ((*((volatile uint32_t *) \ ((AM_REGADDR(GPIO, WTSA) + (((uint32_t)(n) & 0x60) >> 3))))) = \ ((uint32_t) 0x1 << ((uint32_t)(n) % 32))) #define am_hal_gpio_output_toggle(n) \ if ( 1 ) \ { \ AM_CRITICAL_BEGIN \ ((*((volatile uint32_t *) \ ((AM_REGADDR(GPIO, WTA) + (((uint32_t)(n) & 0x60) >> 3))))) ^= \ ((uint32_t) 0x1 << ((uint32_t)(n) % 32))); \ AM_CRITICAL_END \ } #define am_hal_gpio_output_tristate_disable(n) \ ((*((volatile uint32_t *) \ ((AM_REGADDR(GPIO, ENCA) + (((uint32_t)(n) & 0x60) >> 3))))) = \ ((uint32_t) 0x1 << ((uint32_t)(n) % 32))) #define am_hal_gpio_output_tristate_enable(n) \ ((*((volatile uint32_t *) \ ((AM_REGADDR(GPIO, ENSA) + (((uint32_t)(n) & 0x60) >> 3))))) = \ ((uint32_t) 0x1 << ((uint32_t)(n) % 32))) #define am_hal_gpio_output_tristate_toggle(n) \ if ( 1 ) \ { \ AM_CRITICAL_BEGIN \ ((*((volatile uint32_t *) \ ((AM_REGADDR(GPIO, ENA) + (((uint32_t)(n) & 0x60) >> 3))))) ^= \ ((uint32_t) 0x1 << ((uint32_t)(n) % 32))); \ AM_CRITICAL_END \ } //***************************************************************************** //! //! @brief Fast GPIO helper macros. //! //***************************************************************************** // // Define Fast GPIO enable and disable. // #define am_hal_gpio_fastgpio_enable(n) am_hal_gpio_output_tristate_enable(n) #define am_hal_gpio_fastgpio_disable(n) am_hal_gpio_output_tristate_disable(n) // // Macros for accessing Fast GPIO: set, clear, and read. // The 'n' parameter is the pin number. // Note - these macros are most efficient if 'n' is a constant value, and // of course when compiled with -O3. // #define am_hal_gpio_fastgpio_read(n) ((APBDMA->BBINPUT >> (n & 0x7)) & 0x1) #define am_hal_gpio_fastgpio_set(n) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_SET, (1 << (n & 0x7)))) #define am_hal_gpio_fastgpio_clr(n) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_CLEAR, (1 << (n & 0x7)))) #define am_hal_gpio_fastgpio_setmsk(m) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_SET, m)) #define am_hal_gpio_fastgpio_clrmsk(m) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_CLEAR, m)) #define am_hal_gpio_fastgpio_wrval(val) (APBDMA->BBSETCLEAR = \ (_VAL2FLD(APBDMA_BBSETCLEAR_SET, val) | \ _VAL2FLD(APBDMA_BBSETCLEAR_CLEAR, val ^ 0xFF))) #ifdef __cplusplus } #endif #endif // AM_HAL_GPIO_H //***************************************************************************** // // End Doxygen group. //! @} // //*****************************************************************************