Part Number: LAUNCHXL-F28377S
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 //