Part Number: LAUNCHXL-F28377S
Other Parts Discussed in Thread: TMS320F28377D
Hello TI community,
I am currently trying to get the I2C example to work on the LaunchXL-F28377S evaluation board. I wondering if someone could explain to me a little more on the parameters used for the GPIO_SetupPinMux function. The first parameter pin, does this refer to the PZP PIN NO. in the data sheet or does this refer to GPIO'x' pin? I am not sure what the cpu and peripheral parameter refer too. The I2C eeprom example says it requires an external I2C EEPROM connected to the I2C bus at address 0x50. I was wondering if the LaunchXL evaluation board already comes with it and if not, what does it mean by address 0x50.
//###########################################################################
//
// FILE: Example_2837xSI2C_eeprom.c
//
// TITLE: I2C EEPROM Example
//
//! \addtogroup cpu01_example_list
//! <h1>I2C EEPROM Example (i2c_eeprom)</h1>
//!
//! This program will write 1-14 words to EEPROM and read them back.
//! The data written and the EEPROM address written to are contained
//! in the message structure, I2cMsgOut1. The data read back will be
//! contained in the message structure I2cMsgIn1.
//!
//! \b External \b Connections \n
//! - This program requires an external I2C EEPROM connected to
//! the I2C bus at address 0x50.
//!
//
//###########################################################################
// $TI Release: F2837xS Support Library v210 $
// $Release Date: Tue Nov 1 15:35:23 CDT 2016 $
// $Copyright: Copyright (C) 2014-2016 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
//
// Included Files
//
#include "F28x_Project.h"
//
// Defines
//
#define I2C_SLAVE_ADDR 0x50
#define I2C_NUMBYTES 2
#define I2C_EEPROM_HIGH_ADDR 0x00
#define I2C_EEPROM_LOW_ADDR 0x30
//
// Globals
//
struct I2CMSG I2cMsgOut1={ I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_ADDR,
I2C_NUMBYTES,
I2C_EEPROM_HIGH_ADDR,
I2C_EEPROM_LOW_ADDR,
0x12, // Msg Byte 1
0x34}; // Msg Byte 2
struct I2CMSG I2cMsgIn1={ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_ADDR,
I2C_NUMBYTES,
I2C_EEPROM_HIGH_ADDR,
I2C_EEPROM_LOW_ADDR};
struct I2CMSG *CurrentMsgPtr;
Uint16 PassCount;
Uint16 FailCount;
//
// Function Prototypes
//
void I2CA_Init(void);
Uint16 I2CA_WriteData(struct I2CMSG *msg);
Uint16 I2CA_ReadData(struct I2CMSG *msg);
__interrupt void i2c_int1a_isr(void);
void pass(void);
void fail(void);
//
// Main
//
void main(void)
{
Uint16 Error;
Uint16 i;
CurrentMsgPtr = &I2cMsgOut1;
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xS_SysCtrl.c file.
//
InitSysCtrl();
//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xS_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
InitGpio();
//
// For this example, only init the pins for the SCI-A port.
// These functions are found in the F2837xS_Gpio.c file.
//
GPIO_SetupPinMux(32, GPIO_MUX_CPU1, 1);
GPIO_SetupPinMux(33, GPIO_MUX_CPU1, 1);
//
// Step 3. Clear all __interrupts and initialize PIE vector table:
// Disable CPU __interrupts
//
DINT;
//
// Initialize PIE control registers to their default state.
// The default state is all PIE __interrupts disabled and flags
// are cleared.
// This function is found in the F2837xS_PieCtrl.c file.
//
InitPieCtrl();
//
// Disable CPU __interrupts and clear all CPU __interrupt flags:
//
IER = 0x0000;
IFR = 0x0000;
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the __interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2837xS_DefaultIsr.c.
// This function is found in F2837xS_PieVect.c.
//
InitPieVectTable();
//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.I2CA_INT = &i2c_int1a_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
//
// Step 4. Initialize the Device Peripherals:
//
I2CA_Init();
//
// Step 5. User specific code
//
//
// Clear Counters
//
PassCount = 0;
FailCount = 0;
//
// Clear incoming message buffer
//
for (i = 0; i < I2C_MAX_BUFFER_SIZE; i++)
{
I2cMsgIn1.MsgBuffer[i] = 0x0000;
}
//
// Enable __interrupts required for this example
//
//
// Enable I2C __interrupt 1 in the PIE: Group 8 __interrupt 1
//
PieCtrlRegs.PIEIER8.bit.INTx1 = 1;
//
// Enable CPU INT8 which is connected to PIE group 8
//
IER |= M_INT8;
EINT;
for(;;)
{
//
// Write data to EEPROM section
//
//
// Check the outgoing message to see if it should be sent.
// In this example it is initialized to send with a stop bit.
//
if(I2cMsgOut1.MsgStatus == I2C_MSGSTAT_SEND_WITHSTOP)
{
Error = I2CA_WriteData(&I2cMsgOut1);
//
// If communication is correctly initiated, set msg status to busy
// and update CurrentMsgPtr for the __interrupt service routine.
// Otherwise, do nothing and try again next loop. Once message is
// initiated, the I2C __interrupts will handle the rest. Search for
// ICINTR1A_ISR in the i2c_eeprom_isr.c file.
//
if (Error == I2C_SUCCESS)
{
CurrentMsgPtr = &I2cMsgOut1;
I2cMsgOut1.MsgStatus = I2C_MSGSTAT_WRITE_BUSY;
}
}
//
// Read data from EEPROM section
//
//
// Check outgoing message status. Bypass read section if status is
// not inactive.
//
if (I2cMsgOut1.MsgStatus == I2C_MSGSTAT_INACTIVE)
{
//
// Check incoming message status.
//
if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
//
// EEPROM address setup portion
//
while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS)
{
//
// Maybe setup an attempt counter to break an infinite while
// loop. The EEPROM will send back a NACK while it is performing
// a write operation. Even though the write communique is
// complete at this point, the EEPROM could still be busy
// programming the data. Therefore, multiple attempts are
// necessary.
//
}
//
// Update current message pointer and message status
//
CurrentMsgPtr = &I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;
}
//
// Once message has progressed past setting up the internal address
// of the EEPROM, send a restart to read the data bytes from the
// EEPROM. Complete the communique with a stop bit. MsgStatus is
// updated in the __interrupt service routine.
//
else if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_RESTART)
{
//
// Read data portion
//
while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS)
{
//
// Maybe setup an attempt counter to break an infinite while
// loop.
//
}
//
// Update current message pointer and message status
//
CurrentMsgPtr = &I2cMsgIn1;
I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY;
}
}
}
}
//
// I2CA_Init - Initialize I2CA settings
//
void I2CA_Init(void)
{
I2caRegs.I2CSAR.all = 0x0050; // Slave address - EEPROM control code
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY __interrupts
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}
//
// I2CA_WriteData - Transmit I2CA message
//
Uint16 I2CA_WriteData(struct I2CMSG *msg)
{
Uint16 i;
//
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
//
if(I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}
//
// Setup slave address
//
I2caRegs.I2CSAR.all = msg->SlaveAddress;
//
// Check if bus busy
//
if(I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
//
// Setup number of bytes to send
// MsgBuffer + Address
//
I2caRegs.I2CCNT = msg->NumOfBytes+2;
//
// Setup data to send
//
I2caRegs.I2CDXR.all = msg->MemoryHighAddr;
I2caRegs.I2CDXR.all = msg->MemoryLowAddr;
for (i=0; i < msg->NumOfBytes; i++)
{
I2caRegs.I2CDXR.all = *(msg->MsgBuffer+i);
}
//
// Send start as master transmitter
//
I2caRegs.I2CMDR.all = 0x6E20;
return I2C_SUCCESS;
}
//
// I2CA_ReadData - Read I2CA Message
//
Uint16 I2CA_ReadData(struct I2CMSG *msg)
{
//
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
//
if(I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}
I2caRegs.I2CSAR.all = msg->SlaveAddress;
if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
//
// Check if bus busy
//
if(I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR.all = msg->MemoryHighAddr;
I2caRegs.I2CDXR.all = msg->MemoryLowAddr;
I2caRegs.I2CMDR.all = 0x2620; // Send data to setup EEPROM address
}
else if(msg->MsgStatus == I2C_MSGSTAT_RESTART)
{
I2caRegs.I2CCNT = msg->NumOfBytes; // Setup how many bytes to expect
I2caRegs.I2CMDR.all = 0x2C20; // Send restart as master receiver
}
return I2C_SUCCESS;
}
//
// i2c_int1a_isr - I2CA ISR
//
__interrupt void i2c_int1a_isr(void)
{
Uint16 IntSource, i;
//
// Read __interrupt source
//
IntSource = I2caRegs.I2CISRC.all;
//
// Interrupt source = stop condition detected
//
if(IntSource == I2C_SCD_ISRC)
{
//
// If completed message was writing data, reset msg to inactive state
//
if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
}
else
{
//
// If a message receives a NACK during the address setup portion of
// the EEPROM read, the code further below included in the register
// access ready __interrupt source code will generate a stop
// condition. After the stop condition is received (here), set the
// message status to try again. User may want to limit the number of
// retries before generating an error.
if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
}
//
// If completed message was reading EEPROM data, reset msg to inactive
// state and read data from FIFO.
//
else if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_READ_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;
for(i=0; i < I2C_NUMBYTES; i++)
{
CurrentMsgPtr->MsgBuffer[i] = I2caRegs.I2CDRR.all;
}
{
//
// Check received data
//
for(i=0; i < I2C_NUMBYTES; i++)
{
if(I2cMsgIn1.MsgBuffer[i] == I2cMsgOut1.MsgBuffer[i])
{
PassCount++;
}
else
{
FailCount++;
}
}
if(PassCount == I2C_NUMBYTES)
{
pass();
}
else
{
fail();
}
}
}
}
}
//
// Interrupt source = Register Access Ready
// This __interrupt is used to determine when the EEPROM address setup
// portion of the read data communication is complete. Since no stop bit is
// commanded, this flag tells us when the message has been sent instead of
// the SCD flag. If a NACK is received, clear the NACK bit and command a
// stop. Otherwise, move on to the read data portion of the communication.
//
else if(IntSource == I2C_ARDY_ISRC)
{
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
}
else if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_RESTART;
}
}
else
{
//
// Generate some error due to invalid __interrupt source
//
asm(" ESTOP0");
}
//
// Enable future I2C (PIE Group 8) __interrupts
//
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}
//
// pass - Halt debugger and signify pass
//
void pass()
{
asm(" ESTOP0");
for(;;);
}
//
// fail - Halt debugger and signify fail
//
void fail()
{
asm(" ESTOP0");
for(;;);
}
//
// End of file
//
//###########################################################################
//
// FILE: F2837xS_Gpio.c
//
// TITLE: GPIO module support functions
//
//###########################################################################
// $TI Release: F2837xS Support Library v210 $
// $Release Date: Tue Nov 1 15:35:23 CDT 2016 $
// $Copyright: Copyright (C) 2014-2016 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
//
// Included Files
//
#include "F2837xS_device.h"
#include "F2837xS_Examples.h"
//
// InitGpio - Sets all pins to be muxed to GPIO in input mode with pull-ups
// enabled. Also disables open drain and polarity inversion and sets
// the qualification to synchronous. Also unlocks all GPIOs
//
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 in the datasheet. Use the GPIO index row
// (0 to 15) to select a muxing option for the GPIO.
//
void GPIO_SetupPinMux(Uint16 pin, Uint16 cpu, Uint16 peripheral)
{
volatile Uint32 *gpioBaseAddr;
volatile Uint32 *mux, *gmux, *csel;
Uint16 pin32, pin16, pin8;
pin32 = pin % 32;
pin16 = pin % 16;
pin8 = pin % 8;
gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (pin/32)*GPY_CTRL_OFFSET;
//
//Sanity check for valid cpu and peripheral values
//
if (cpu > GPIO_MUX_CPU2CLA || peripheral > 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)((peripheral >> 2) & 0x3UL) << (2*pin16);
*mux |= (Uint32)(peripheral & 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 pin, Uint16 output, Uint16 flags)
{
volatile Uint32 *gpioBaseAddr;
volatile Uint32 *dir, *pud, *inv, *odr, *qsel;
Uint32 pin32, pin16, pinMask, qual;
pin32 = pin % 32;
pin16 = pin % 16;
pinMask = 1UL << pin32;
gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (pin/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 pin, Uint16 flags)
{
volatile Uint32 *gpioBaseAddr;
volatile Uint32 *lock;
Uint32 pin32, pinMask;
pin32 = pin % 32;
pinMask = 1UL << pin32;
gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (pin/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;
}
//
// GPIO_SetupXINT1Gpio - External interrupt setup
//
void GPIO_SetupXINT1Gpio(Uint16 pin)
{
EALLOW;
InputXbarRegs.INPUT4SELECT = pin; //Set XINT1 source to GPIO-pin
EDIS;
}
//
// GPIO_SetupXINT2Gpio - External interrupt setup
//
void GPIO_SetupXINT2Gpio(Uint16 pin)
{
EALLOW;
InputXbarRegs.INPUT5SELECT = pin; //Set XINT2 source to GPIO-pin
EDIS;
}
//
// GPIO_SetupXINT3Gpio - External interrupt setup
//
void GPIO_SetupXINT3Gpio(Uint16 pin)
{
EALLOW;
InputXbarRegs.INPUT6SELECT = pin; //Set XINT3 source to GPIO-pin
EDIS;
}
//
// GPIO_SetupXINT4Gpio - External interrupt setup
//
void GPIO_SetupXINT4Gpio(Uint16 pin)
{
EALLOW;
InputXbarRegs.INPUT13SELECT = pin; //Set XINT4 source to GPIO-pin
EDIS;
}
//
// GPIO_SetupXINT5Gpio - External interrupt setup
//
void GPIO_SetupXINT5Gpio(Uint16 pin)
{
EALLOW;
InputXbarRegs.INPUT14SELECT = pin; //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 - Enable IO pullups for specific package
//
void GPIO_EnableUnbondedIOPullups()
{
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
//
}
}
//
// 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 pin)
{
volatile Uint32 *gpioDataReg;
Uint16 pinVal;
gpioDataReg = (volatile Uint32 *)&GpioDataRegs + (pin/32)*GPY_DATA_OFFSET;
pinVal = (gpioDataReg[GPYDAT] >> (pin % 32)) & 0x1;
return pinVal;
}
//
// GPIO_WritePin - Set the GPyDAT register bit for the specified pin.
//
void GPIO_WritePin(Uint16 pin, Uint16 outVal)
{
volatile Uint32 *gpioDataReg;
Uint32 pinMask;
gpioDataReg = (volatile Uint32 *)&GpioDataRegs + (pin/32)*GPY_DATA_OFFSET;
pinMask = 1UL << (pin % 32);
if (outVal == 0)
{
gpioDataReg[GPYCLEAR] = pinMask;
}
else
{
gpioDataReg[GPYSET] = pinMask;
}
}
//
// End of file
//