123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- //###########################################################################
- //
- // FILE: F2837xD_Gpio.c
- //
- // TITLE: GPIO module support functions
- //
- //###########################################################################
- // $TI Release: F2837xD Support Library v3.05.00.00 $
- // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
- // $Copyright:
- // Copyright (C) 2013-2018 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.
- // $
- //###########################################################################
- //
- // Included Files
- //
- #include "F2837xD_device.h"
- #include "F2837xD_Examples.h"
- //
- //Low-level functions for GPIO configuration (CPU1 only)
- //
- #ifdef CPU1
- //
- // InitGpio - Sets all pins to be muxed to GPIO in input mode with pull-ups
- // enabled. Also resets CPU control to CPU1 and disables open
- // drain and polarity inversion and sets the qualification to
- // synchronous. Also unlocks all GPIOs. Only one CPU should call
- // this function.
- //
- void InitGpio()
- {
- volatile Uint32 *gpioBaseAddr;
- Uint16 regOffset;
- //
- //Disable pin locks
- //
- EALLOW;
- GpioCtrlRegs.GPALOCK.all = 0x00000000;
- GpioCtrlRegs.GPBLOCK.all = 0x00000000;
- GpioCtrlRegs.GPCLOCK.all = 0x00000000;
- GpioCtrlRegs.GPDLOCK.all = 0x00000000;
- GpioCtrlRegs.GPELOCK.all = 0x00000000;
- GpioCtrlRegs.GPFLOCK.all = 0x00000000;
- //
- // Fill all registers with zeros. Writing to each register separately
- // for six GPIO modules would make this function *very* long.
- // Fortunately, we'd be writing them all with zeros anyway, so this
- // saves a lot of space.
- //
- gpioBaseAddr = (Uint32 *)&GpioCtrlRegs;
- for (regOffset = 0; regOffset < sizeof(GpioCtrlRegs)/2; regOffset++)
- {
- //
- //Hack to avoid enabling pull-ups on all pins. GPyPUD is offset
- //0x0C in each register group of 0x40 words. Since this is a
- //32-bit pointer, the addresses must be divided by 2.
- //
- if (regOffset % (0x40/2) != (0x0C/2))
- {
- gpioBaseAddr[regOffset] = 0x00000000;
- }
- }
- gpioBaseAddr = (Uint32 *)&GpioDataRegs;
- for (regOffset = 0; regOffset < sizeof(GpioDataRegs)/2; regOffset++)
- {
- gpioBaseAddr[regOffset] = 0x00000000;
- }
- EDIS;
- }
- //
- // GPIO_SetupPinMux - Set the peripheral muxing for the specified pin. The
- // appropriate parameters can be found in the GPIO Muxed
- // Pins table(4.4) in the datasheet. Use the GPIO index
- // row (0 to 15) to select a muxing option for the GPIO.
- //
- void GPIO_SetupPinMux(Uint16 gpioNumber, Uint16 cpu, Uint16 muxPosition)
- {
- volatile Uint32 *gpioBaseAddr;
- volatile Uint32 *mux, *gmux, *csel;
- Uint16 pin32, pin16, pin8;
- pin32 = gpioNumber % 32;
- pin16 = gpioNumber % 16;
- pin8 = gpioNumber % 8;
- gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (gpioNumber/32)*GPY_CTRL_OFFSET;
- //
- //Sanity check for valid cpu and peripheral values
- //
- if (cpu > GPIO_MUX_CPU2CLA || muxPosition > 0xF)
- return;
- //
- //Create pointers to the appropriate registers. This is a workaround
- //for the way GPIO registers are defined. The standard definition
- //in the header file makes it very easy to do named accesses of one
- //register or bit, but hard to do arbitrary numerical accesses. It's
- //easier to have an array of GPIO modules with identical registers,
- //including arrays for multi-register groups like GPyCSEL1-4. But
- //the header file doesn't define anything we can turn into an array,
- //so manual pointer arithmetic is used instead.
- //
- mux = gpioBaseAddr + GPYMUX + pin32/16;
- gmux = gpioBaseAddr + GPYGMUX + pin32/16;
- csel = gpioBaseAddr + GPYCSEL + pin32/8;
- //
- //Now for the actual function
- //
- EALLOW;
- //
- //To change the muxing, set the peripheral mux to 0/GPIO first to avoid
- //glitches, then change the group mux, then set the peripheral mux to
- //its target value. Finally, set the CPU select. This procedure is
- //described in the TRM. Unfortunately, since we don't know the pin in
- //advance we can't hardcode a bitfield reference, so there's some
- //tricky bit twiddling here.
- //
- *mux &= ~(0x3UL << (2*pin16));
- *gmux &= ~(0x3UL << (2*pin16));
- *gmux |= (Uint32)((muxPosition >> 2) & 0x3UL) << (2*pin16);
- *mux |= (Uint32)(muxPosition & 0x3UL) << (2*pin16);
- *csel &= ~(0x3L << (4*pin8));
- *csel |= (Uint32)(cpu & 0x3L) << (4*pin8);
- //
- //WARNING: This code does not touch the analog mode select registers,
- //which are needed to give the USB module control of its IOs.
- //
- EDIS;
- }
- //
- // GPIO_SetupPinOptions - Setup up the GPIO input/output options for the
- // specified pin.
- //
- //The flags are a 16-bit mask produced by ORing together options.
- //For input pins, the valid flags are:
- //GPIO_PULLUP Enable pull-up
- //GPIO_INVERT Enable input polarity inversion
- //GPIO_SYNC Synchronize the input latch to PLLSYSCLK
- // (default -- you don't need to specify this)
- //GPIO_QUAL3 Use 3-sample qualification
- //GPIO_QUAL6 Use 6-sample qualification
- //GPIO_ASYNC Do not use synchronization or qualification
- //(Note: only one of SYNC, QUAL3, QUAL6, or ASYNC is allowed)
- //
- //For output pins, the valid flags are:
- //GPIO_OPENDRAIN Output in open drain mode
- //GPIO_PULLUP If open drain enabled, also enable the pull-up
- //and the input qualification flags (SYNC/QUAL3/QUAL6/SYNC) listed above.
- //
- //With no flags, the default input state is synchronous with no
- //pull-up or polarity inversion. The default output state is
- //the standard digital output.
- //
- void GPIO_SetupPinOptions(Uint16 gpioNumber, Uint16 output, Uint16 flags)
- {
- volatile Uint32 *gpioBaseAddr;
- volatile Uint32 *dir, *pud, *inv, *odr, *qsel;
- Uint32 pin32, pin16, pinMask, qual;
- pin32 = gpioNumber % 32;
- pin16 = gpioNumber % 16;
- pinMask = 1UL << pin32;
- gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (gpioNumber/32)*GPY_CTRL_OFFSET;
- //
- //Create pointers to the appropriate registers. This is a workaround
- //for the way GPIO registers are defined. The standard definition
- //in the header file makes it very easy to do named accesses of one
- //register or bit, but hard to do arbitrary numerical accesses. It's
- //easier to have an array of GPIO modules with identical registers,
- //including arrays for multi-register groups like GPyQSEL1-2. But
- //the header file doesn't define anything we can turn into an array,
- //so manual pointer arithmetic is used instead.
- //
- dir = gpioBaseAddr + GPYDIR;
- pud = gpioBaseAddr + GPYPUD;
- inv = gpioBaseAddr + GPYINV;
- odr = gpioBaseAddr + GPYODR;
- qsel = gpioBaseAddr + GPYQSEL + pin32/16;
- EALLOW;
- //
- //Set the data direction
- //
- *dir &= ~pinMask;
- if (output == 1)
- {
- //
- //Output, with optional open drain mode and pull-up
- //
- *dir |= pinMask;
- //
- //Enable open drain if necessary
- //
- if (flags & GPIO_OPENDRAIN)
- {
- *odr |= pinMask;
- }
- else
- {
- *odr &= ~pinMask;
- }
- //
- //Enable pull-up if necessary. Open drain mode must be active.
- //
- if (flags & (GPIO_OPENDRAIN | GPIO_PULLUP))
- {
- *pud &= ~pinMask;
- }
- else
- {
- *pud |= pinMask;
- }
- }
- else
- {
- //
- //Input, with optional pull-up, qualification, and polarity
- //inversion
- //
- *dir &= ~pinMask;
- //
- //Enable pull-up if necessary
- //
- if (flags & GPIO_PULLUP)
- {
- *pud &= ~pinMask;
- }
- else
- {
- *pud |= pinMask;
- }
- //
- //Invert polarity if necessary
- //
- if (flags & GPIO_INVERT)
- {
- *inv |= pinMask;
- }
- else
- {
- *inv &= ~pinMask;
- }
- }
- //
- //Extract the qualification parameter and load it into the register.
- //This is also needed for open drain outputs, so we might as well do it
- //all the time.
- //
- qual = (flags & GPIO_ASYNC) / GPIO_QUAL3;
- *qsel &= ~(0x3L << (2 * pin16));
- if (qual != 0x0)
- {
- *qsel |= qual << (2 * pin16);
- }
- EDIS;
- }
- //
- // GPIO_SetupLock - Enable or disable the GPIO register bit lock for the
- // specified pin.
- // The valid flags are:
- // GPIO_UNLOCK - Unlock the pin setup register bits for
- // the specified pin
- // GPIO_LOCK - Lock the pin setup register bits for the
- // specified pin
- //
- void GPIO_SetupLock(Uint16 gpioNumber, Uint16 flags)
- {
- volatile Uint32 *gpioBaseAddr;
- volatile Uint32 *lock;
- Uint32 pin32, pinMask;
- pin32 = gpioNumber % 32;
- pinMask = 1UL << pin32;
- gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (gpioNumber/32)*GPY_CTRL_OFFSET;
- //
- //Create pointers to the appropriate registers. This is a workaround
- //for the way GPIO registers are defined. The standard definition
- //in the header file makes it very easy to do named accesses of one
- //register or bit, but hard to do arbitrary numerical accesses. It's
- //easier to have an array of GPIO modules with identical registers,
- //including arrays for multi-register groups like GPyQSEL1-2. But
- //the header file doesn't define anything we can turn into an array,
- //so manual pointer arithmetic is used instead.
- //
- lock = gpioBaseAddr + GPYLOCK;
- EALLOW;
- if(flags)
- {
- //Lock the pin
- *lock |= pinMask;
- }
- else
- {
- //Unlock the pin
- *lock &= ~pinMask;
- }
- EDIS;
- }
- //
- //External interrupt setup
- //
- void GPIO_SetupXINT1Gpio(Uint16 gpioNumber)
- {
- EALLOW;
- InputXbarRegs.INPUT4SELECT = gpioNumber; //Set XINT1 source to GPIO-pin
- EDIS;
- }
- void GPIO_SetupXINT2Gpio(Uint16 gpioNumber)
- {
- EALLOW;
- InputXbarRegs.INPUT5SELECT = gpioNumber; //Set XINT2 source to GPIO-pin
- EDIS;
- }
- void GPIO_SetupXINT3Gpio(Uint16 gpioNumber)
- {
- EALLOW;
- InputXbarRegs.INPUT6SELECT = gpioNumber; //Set XINT3 source to GPIO-pin
- EDIS;
- }
- void GPIO_SetupXINT4Gpio(Uint16 gpioNumber)
- {
- EALLOW;
- InputXbarRegs.INPUT13SELECT = gpioNumber; //Set XINT4 source to GPIO-pin
- EDIS;
- }
- void GPIO_SetupXINT5Gpio(Uint16 gpioNumber)
- {
- EALLOW;
- InputXbarRegs.INPUT14SELECT = gpioNumber; //Set XINT5 source to GPIO-pin
- EDIS;
- }
- //
- //GPIO_EnableUnbondedIOPullupsFor176Pin - Enable pullups for the unbonded
- // GPIOs on the 176PTP package:
- // GPIOs Grp Bits
- // 95-132 C 31
- // D 31:0
- // E 4:0
- // 134-168 E 31:6
- // F 8:0
- //
- void GPIO_EnableUnbondedIOPullupsFor176Pin()
- {
- EALLOW;
- GpioCtrlRegs.GPCPUD.all = ~0x80000000; //GPIO 95
- GpioCtrlRegs.GPDPUD.all = ~0xFFFFFFF7; //GPIOs 96-127
- GpioCtrlRegs.GPEPUD.all = ~0xFFFFFFDF; //GPIOs 128-159 except for 133
- GpioCtrlRegs.GPFPUD.all = ~0x000001FF; //GPIOs 160-168
- EDIS;
- }
- //
- // GPIO_EnableUnbondedIOPullupsFor100Pin - Enable pullups for the unbonded
- // GPIOs on the 100PZ package:
- // GPIOs Grp Bits
- // 0-1 A 1:0
- // 5-9 A 9:5
- // 22-40 A 31:22
- // B 8:0
- // 44-57 B 25:12
- // 67-68 C 4:3
- // 74-77 C 13:10
- // 79-83 C 19:15
- // 93-168 C 31:29
- // D 31:0
- // E 31:0
- // F 8:0
- //
- void GPIO_EnableUnbondedIOPullupsFor100Pin()
- {
- EALLOW;
- GpioCtrlRegs.GPAPUD.all = ~0xFFC003E3; //GPIOs 0-1, 5-9, 22-31
- GpioCtrlRegs.GPBPUD.all = ~0x03FFF1FF; //GPIOs 32-40, 44-57
- GpioCtrlRegs.GPCPUD.all = ~0xE10FBC18; //GPIOs 67-68, 74-77, 79-83, 93-95
- GpioCtrlRegs.GPDPUD.all = ~0xFFFFFFF7; //GPIOs 96-127
- GpioCtrlRegs.GPEPUD.all = ~0xFFFFFFFF; //GPIOs 128-159
- GpioCtrlRegs.GPFPUD.all = ~0x000001FF; //GPIOs 160-168
- EDIS;
- }
- //
- // GPIO_EnableUnbondedIOPullups - InitSysCtrl would call this function
- // this takes care of enabling IO pullups.
- //
- void GPIO_EnableUnbondedIOPullups()
- {
- //
- //bits 8-10 have pin count
- //
- unsigned char pin_count = ((DevCfgRegs.PARTIDL.all & 0x00000700) >> 8) ;
- //
- //5 = 100 pin
- //6 = 176 pin
- //7 = 337 pin
- //
- if(pin_count == 5)
- {
- GPIO_EnableUnbondedIOPullupsFor100Pin();
- }
- else if (pin_count == 6)
- {
- GPIO_EnableUnbondedIOPullupsFor176Pin();
- }
- else
- {
- //do nothing - this is 337 pin package
- }
- }
- #endif //CPU1
- //
- // GPIO_ReadPin - Read the GPyDAT register bit for the specified pin. Note that
- // this returns the actual state of the pin, not the state of
- // the output latch.
- //
- Uint16 GPIO_ReadPin(Uint16 gpioNumber)
- {
- volatile Uint32 *gpioDataReg;
- Uint16 pinVal;
- gpioDataReg = (volatile Uint32 *)&GpioDataRegs + (gpioNumber/32)*GPY_DATA_OFFSET;
- pinVal = (gpioDataReg[GPYDAT] >> (gpioNumber % 32)) & 0x1;
- return pinVal;
- }
- //
- // GPIO_WritePin - Set the GPyDAT register bit for the specified pin.
- //
- void GPIO_WritePin(Uint16 gpioNumber, Uint16 outVal)
- {
- volatile Uint32 *gpioDataReg;
- Uint32 pinMask;
- gpioDataReg = (volatile Uint32 *)&GpioDataRegs + (gpioNumber/32)*GPY_DATA_OFFSET;
- pinMask = 1UL << (gpioNumber % 32);
- if (outVal == 0)
- {
- gpioDataReg[GPYCLEAR] = pinMask;
- }
- else
- {
- gpioDataReg[GPYSET] = pinMask;
- }
- }
- //
- // End of file
- //
|