/* * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * 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 * OWNER 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. * */ //***************************************************************************** // // pin.c // // Mapping of peripherals to pins. // //***************************************************************************** //***************************************************************************** // //! \addtogroup pin_api //! @{ // //***************************************************************************** #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "inc/hw_ocp_shared.h" #include "pin.h" //***************************************************************************** // Macros //***************************************************************************** #define PAD_MODE_MASK 0x0000000F #define PAD_STRENGTH_MASK 0x000000E0 #define PAD_TYPE_MASK 0x00000310 #define PAD_CONFIG_BASE ((OCP_SHARED_BASE + \ OCP_SHARED_O_GPIO_PAD_CONFIG_0)) //***************************************************************************** // PIN to PAD matrix //***************************************************************************** static const unsigned long g_ulPinToPadMap[64] = { 10,11,12,13,14,15,16,17,255,255,18, 19,20,21,22,23,24,40,28,29,25,255, 255,255,255,255,255,255,26,27,255,255,255, 255,255,255,255,255,255,255,255,255,255,255, 31,255,255,255,255,0,255,32,30,255,1, 255,2,3,4,5,6,7,8,9 }; //***************************************************************************** // //! Configures pin mux for the specified pin. //! //! \param ulPin is a valid pin. //! \param ulPinMode is one of the valid mode //! //! This function configures the pin mux that selects the peripheral function //! associated with a particular SOC pin. Only one peripheral function at a //! time can be associated with a pin, and each peripheral function should //! only be associated with a single pin at a time. //! //! \return none // //***************************************************************************** void PinModeSet(unsigned long ulPin,unsigned long ulPinMode) { unsigned long ulPad; // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE); // // Set the mode. // HWREG(ulPad) = (((HWREG(ulPad) & ~PAD_MODE_MASK) | ulPinMode) & ~(3<<10)); } //***************************************************************************** // //! Gets current pin mux configuration of specified pin. //! //! \param ulPin is a valid pin. //! //! This function get the current configuration of the pin mux. //! //! \return Returns current pin mode if \e ulPin is valid, 0xFF otherwise. // //***************************************************************************** unsigned long PinModeGet(unsigned long ulPin) { unsigned long ulPad; // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE) ; // // return the mode. // return (HWREG(ulPad) & PAD_MODE_MASK); } //***************************************************************************** // //! Sets the direction of the specified pin(s). //! //! \param ulPin is one of the valid pin. //! \param ulPinIO is the pin direction and/or mode. //! //! This function configures the specified pin(s) as either input only or //! output only or it configures the pin to be under hardware control. //! //! The parameter \e ulPinIO is an enumerated data type that can be one of //! the following values: //! //! - \b PIN_DIR_MODE_IN //! - \b PIN_DIR_MODE_OUT //! - \b PIN_DIR_MODE_HW //! //! where \b PIN_DIR_MODE_IN specifies that the pin is programmed as a //! input only, \b PIN_DIR_MODE_OUT specifies that the pin is //! programmed output only, and \b PIN_DIR_MODE_HW specifies that the pin is //! placed under hardware control. //! //! //! \return None. // //***************************************************************************** void PinDirModeSet(unsigned long ulPin, unsigned long ulPinIO) { unsigned long ulPad; // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE); // // Set the direction // HWREG(ulPad) = ((HWREG(ulPad) & ~0xC00) | ulPinIO); } //***************************************************************************** // //! Gets the direction of a pin. //! //! \param ulPin is one of the valid pin. //! //! This function gets the direction and control mode for a specified pin on //! the selected GPIO port. The pin can be configured as either an input only //! or output only, or it can be under hardware control. The type of control //! and direction are returned as an enumerated data type. //! //! \return Returns one of the enumerated data types described for //! GPIODirModeSet(). // //***************************************************************************** unsigned long PinDirModeGet(unsigned long ulPin) { unsigned long ulPad; // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE); // // Return the direction // return ((HWREG(ulPad) & 0xC00)); } //***************************************************************************** // //! Gets Pin output drive strength and Type //! //! \param ulPin is one of the valid pin //! \param pulPinStrength is pointer to storage for output drive strength //! \param pulPinType is pinter to storage for pin type //! //! This function gets the pin type and output drive strength for the pin //! specified by \e ulPin parameter. Parameters \e pulPinStrength and //! \e pulPinType corresponds to the values used in PinConfigSet(). //! //! //! \return None. // //***************************************************************************** void PinConfigGet(unsigned long ulPin,unsigned long *pulPinStrength, unsigned long *pulPinType) { unsigned long ulPad; // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE); // // Get the type // *pulPinType = (HWREG(ulPad) & PAD_TYPE_MASK); // // Get the output drive strength // *pulPinStrength = (HWREG(ulPad) & PAD_STRENGTH_MASK); } //***************************************************************************** // //! Configure Pin output drive strength and Type //! //! \param ulPin is one of the valid pin //! \param ulPinStrength is logical OR of valid output drive strengths. //! \param ulPinType is one of the valid pin type. //! //! This function sets the pin type and strength for the pin specified by //! \e ulPin parameter. //! //! The parameter \e ulPinStrength should be one of the following //! - \b PIN_STRENGTH_2MA //! - \b PIN_STRENGTH_4MA //! - \b PIN_STRENGTH_6MA //! //! //! The parameter \e ulPinType should be one of the following //! For standard type //! //! - \b PIN_TYPE_STD //! - \b PIN_TYPE_STD_PU //! - \b PIN_TYPE_STD_PD //! //! And for Open drain type //! //! - \b PIN_TYPE_OD //! - \b PIN_TYPE_OD_PU //! - \b PIN_TYPE_OD_PD //! //! \return None. // //***************************************************************************** void PinConfigSet(unsigned long ulPin,unsigned long ulPinStrength, unsigned long ulPinType) { unsigned long ulPad; // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Write the register // if(ulPinType == PIN_TYPE_ANALOG) { // // Isolate the input // HWREG(0x4402E144) |= ((0x80 << ulPad) & (0x1E << 8)); // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE); // // Isolate the output // HWREG(ulPad) = 0xC00; } else { // // Enable the input // HWREG(0x4402E144) &= ~((0x80 << ulPad) & (0x1E << 8)); // // Calculate the register address // ulPad = ((ulPad << 2) + PAD_CONFIG_BASE); // // Write the configuration // HWREG(ulPad) = ((HWREG(ulPad) & ~(PAD_STRENGTH_MASK | PAD_TYPE_MASK)) | (ulPinStrength | ulPinType )); } } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by UART peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The UART pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin(s); other configurations may work as well depending upon the //! board setup (for example, using the on-chip pull-ups). //! //! //! \note This function cannot be used to turn any pin into a UART pin; it //! only sets the pin mode and configures it for proper UART operation. //! //! //! \return None. // //***************************************************************************** void PinTypeUART(unsigned long ulPin,unsigned long ulPinMode) { // // Set the pin to specified mode // PinModeSet(ulPin,ulPinMode); // // Set the pin for standard operation // PinConfigSet(ulPin,PIN_STRENGTH_2MA,PIN_TYPE_STD); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by I2C peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The I2C pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! the pin. //! //! //! \note This function cannot be used to turn any pin into a I2C pin; it //! only sets the pin mode and configures it for proper I2C operation. //! //! //! \return None. // //***************************************************************************** void PinTypeI2C(unsigned long ulPin,unsigned long ulPinMode) { // // Set the pin to specified mode // PinModeSet(ulPin,ulPinMode); // // Set the pin for open-drain operation with a weak pull-up. // PinConfigSet(ulPin,PIN_STRENGTH_2MA,PIN_TYPE_OD_PU); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by SPI peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The SPI pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin. //! //! //! \note This function cannot be used to turn any pin into a SPI pin; it //! only sets the pin mode and configures it for proper SPI operation. //! //! //! \return None. // //***************************************************************************** void PinTypeSPI(unsigned long ulPin,unsigned long ulPinMode) { // // Set the pin to specified mode // PinModeSet(ulPin,ulPinMode); // // Set the pin for standard operation // PinConfigSet(ulPin,PIN_STRENGTH_2MA|PIN_STRENGTH_4MA,PIN_TYPE_STD); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by I2S peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The I2S pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin. //! //! //! \note This function cannot be used to turn any pin into a I2S pin; it //! only sets the pin mode and configures it for proper I2S operation. //! //! \return None. // //***************************************************************************** void PinTypeI2S(unsigned long ulPin,unsigned long ulPinMode) { // // Set the pin to specified mode // PinModeSet(ulPin,ulPinMode); // // Set the pin for standard operation // PinConfigSet(ulPin,PIN_STRENGTH_2MA|PIN_STRENGTH_4MA,PIN_TYPE_STD); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by Timer peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The timer PWM pins must be properly configured for the Timer peripheral to //! function correctly. This function provides a typical configuration for //! those pin; other configurations may work as well depending upon the //! board setup (for example, using the on-chip pull-ups). //! //! //! \note This function cannot be used to turn any pin into a timer PWM pin; it //! only sets the pin mode and configures it for proper timer PWM operation. //! //! \return None. // //***************************************************************************** void PinTypeTimer(unsigned long ulPin,unsigned long ulPinMode) { // // Set the pin to specified mode // PinModeSet(ulPin,ulPinMode); // // Set the pin for standard operation // PinConfigSet(ulPin,PIN_STRENGTH_2MA|PIN_STRENGTH_4MA,PIN_TYPE_STD); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by Camera peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The Camera pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin. //! //! //! \note This function cannot be used to turn any pin into a Camera pin; it //! only sets the pin mode and configures it for proper Camera operation. //! //! \return None. // //***************************************************************************** void PinTypeCamera(unsigned long ulPin,unsigned long ulPinMode) { // // Set the pin to specified mode // PinModeSet(ulPin,ulPinMode); // // Set the pin for standard operation // PinConfigSet(ulPin,PIN_STRENGTH_2MA|PIN_STRENGTH_4MA,PIN_TYPE_STD); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by GPIO peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! \param bOpenDrain is one to decide either OpenDrain or STD //! //! The GPIO pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin. //! //! //! \return None. // //***************************************************************************** void PinTypeGPIO(unsigned long ulPin,unsigned long ulPinMode,tBoolean bOpenDrain) { // // Set the pin for standard push-pull operation. // if(bOpenDrain) { PinConfigSet(ulPin, PIN_STRENGTH_2MA, PIN_TYPE_OD); } else { PinConfigSet(ulPin, PIN_STRENGTH_2MA, PIN_TYPE_STD); } // // Set the pin to specified mode // PinModeSet(ulPin, ulPinMode); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by ADC //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The ADC pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin. //! //! //! \note This function cannot be used to turn any pin into a ADC pin; it //! only sets the pin mode and configures it for proper ADC operation. //! //! \return None. // //***************************************************************************** void PinTypeADC(unsigned long ulPin,unsigned long ulPinMode) { // // Configure the Pin // PinConfigSet(ulPin,PIN_STRENGTH_2MA,PIN_TYPE_ANALOG); } //***************************************************************************** // //! Sets the pin mode and configures the pin for use by SD Host peripheral //! //! \param ulPin is one of the valid pin. //! \param ulPinMode is one of the valid pin mode. //! //! The MMC pins must be properly configured for the peripheral to //! function correctly. This function provides a typical configuration for //! those pin. //! //! //! \note This function cannot be used to turn any pin into a SD Host pin; it //! only sets the pin mode and configures it for proper SD Host operation. //! //! \return None. // //***************************************************************************** void PinTypeSDHost(unsigned long ulPin,unsigned long ulPinMode) { // // Set pin mode // PinModeSet(ulPin,ulPinMode); // // Configure the Pin // PinConfigSet(ulPin,PIN_STRENGTH_2MA,PIN_TYPE_STD); } //***************************************************************************** // //! Sets the hysteresis for all the pins //! //! \param ulHysteresis is one of the valid predefined hysterisys values //! //! This function sets the hysteresis vlaue for all the pins. The parameter //! \e ulHysteresis can be on one the following: //! -\b PIN_HYSTERESIS_OFF - To turn Off hysteresis, default on POR //! -\b PIN_HYSTERESIS_10 - To turn On hysteresis, 10% //! -\b PIN_HYSTERESIS_20 - To turn On hysteresis, 20% //! -\b PIN_HYSTERESIS_30 - To turn On hysteresis, 30% //! -\b PIN_HYSTERESIS_40 - To turn On hysteresis, 40% //! //! \return None. // //***************************************************************************** void PinHysteresisSet(unsigned long ulHysteresis) { unsigned long ulRegValue; // // Read the current value // ulRegValue = (HWREG( OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CMN_CONFIG ) & ~(0x0000001C)); // // Set the new Hysteresis // if( ulHysteresis != PIN_HYSTERESIS_OFF ) { ulRegValue |= (ulHysteresis & 0x0000001C); } // // Write the new value // HWREG( OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CMN_CONFIG ) = ulRegValue; } //***************************************************************************** // //! Sets the level of the pin when locked //! //! \param ulPin is one of the valid pin. //! \param ucLevel is the level the pin drives when locked //! //! This function sets the pin level when the pin is locked using //! \sa PinLock() API. //! //! By default all pins are set to drive 0. //! //! \note Use case is to park the pins when entering LPDS //! //! \return None. // //***************************************************************************** void PinLockLevelSet(unsigned long ulPin, unsigned char ucLevel) { unsigned long ulPad; // // Supported only in ES2.00 and Later devices i.e. ROM Version 2.x.x or greater // if( (HWREG(0x00000400) & 0xFFFF) >= 2 ) { // // Get the corresponding Pad // ulPad = g_ulPinToPadMap[ulPin & 0x3F]; // // Get the required bit // ulPad = 1 << ulPad; if(ucLevel) { HWREG( OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_6 ) |= ulPad; } else { HWREG( OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_6 ) &= ~ulPad; } } } //***************************************************************************** // //! Locks all the pins to configured level(s). //! //! \param ulOutEnable the bit-packed representation of pins to be set as output //! //! This function locks all the pins to the pre-configure level. By default //! the pins are set to drive 0. Default level can be changed using //! \sa PinLockLevelSet() API. //! //! The \e ulOutEnable paramter is bit-packed representation of pins that //! are required to be enabled as output. If a bit is set 1, the corresponding //! pin (as shown below) are set and locked as output. //! //! |------|-----------------------------------------------| //! | Bit |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| //! |------|-----------------------------------------------| //! | Pin |xx|xx|20|19|30|29|21|17|16|15|14|13|12|11|08|07| //! |------|-----------------------------------------------| //! //! |------|-----------------------------------------------| //! | Bit |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| //! |------|-----------------------------------------------| //! | Pin |06|05|04|03|02|01|64|63|62|61|60|59|58|57|55|50| //! |------|-----------------------------------------------| //! //! //! \note Use case is to park the pins when entering LPDS //! //! \return None. // //***************************************************************************** void PinLock(unsigned long ulOutEnable) { // // Supported only in ES2.00 and Later devices i.e. ROM Version 2.x.x or greater // if( (HWREG(0x00000400) & 0xFFFF) >= 2 ) { // // Enable/disable the pin(s) output // HWREG( OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_7 ) = ~ulOutEnable; // // Lock the pins to selected levels // HWREG( OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_5 ) |= (3 << 24); } } //***************************************************************************** // //! Unlocks all the pins. //! //! This function unlocks all the pins and can be used for peripheral function. //! //! By default all the pins are in unlocked state. //! //! \note Use case is to un-park the pins when exiting LPDS //! //! \return None. // //***************************************************************************** void PinUnlock() { // // Supported only in ES2.00 and Later devices i.e. ROM Version 2.x.x or greater // if( (HWREG(0x00000400) & 0xFFFF) >= 2 ) { // // Unlock the pins // HWREG( OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_5 ) &= ~(3 << 24); } } //***************************************************************************** // // Gets pad number from pin number // // \param ulPin is a valid pin number // // This function return the pad corresponding to the specified pin // // \return Pad number on success, 0xFF otherwise // //***************************************************************************** unsigned long PinToPadGet(unsigned long ulPin) { // // Return the corresponding Pad // return g_ulPinToPadMap[ulPin & 0x3F]; } //***************************************************************************** // // Gets pin number from pad number // // \param ulPad is a valid pad number // // This function return the pin corresponding to the specified pad // // \return Pin number on success, 0xFF otherwise // //***************************************************************************** unsigned long PinFromPadGet(unsigned long ulPad) { unsigned long ulPin; // // search and return the pin number // for(ulPin=0; ulPin < sizeof(g_ulPinToPadMap)/4; ulPin++) { if(g_ulPinToPadMap[ulPin] == ulPad) { return ulPin; } } return 0xFF; } //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************