Part Number: MSP432P401R
Hello,
As a part of my senior design project, I am trying to drive an I2C PWM LED Driver (PCA9685 from NXP Sem, DataSheet attached). To test I understand the I2C protocol, I am just trying to turn on 1 LED channel by writing a value to a control register and reading that value back. PCA9685.pdf
Here is my code.
/* --COPYRIGHT--,BSD * Copyright (c) 2017, Texas Instruments Incorporated * All rights reserved. * * 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. * --/COPYRIGHT--*/ /****************************************************************************** * MSP432P4 I2C - EUSCI_B0 I2C Master TX/RX bytes to PCA9685A Slave-Repeated Start * * Description: This demo connects two MSP432's via the I2C bus. This is the * MASTER CODE.The master transmits 2B to the slave, then receives a byte. * The master transmits two bytes to the slave followed by a * repeated start and a single-byte read from the slave. * This is a common operation for bytes from I2C slave devices such as EEPROMs. * The transaction for the I2C that is written looks as follows: * ________________________________________________________ * | Start | WData | WData | Start | RData | | * | 0x48 Addr | 0x007 | 0x013 |0x48 Addr | 0x13 | Stop | * | W | | | R | | | * |___________|_______|_______|__________|________|_______| * * ACLK = n/a, MCLK = HSMCLK = SMCLK = BRCLK = default DCO = ~3.0MHz * * /|\ /|\ * PCA9685 10k 10k MSP432P401R * slave | | master * ----------------- | | ----------------- * | P27/SDA|<-|----+->|P6.4/UCB1SDA | * | | | | | * | | | | | * | P26/SCL|<-+------>|P6.5/UCB1SCL | * | | | P2.7|-- Error * | | | P2.6|-- Activity * *****************************************************************************/ /* DriverLib Defines */ #include <ti/devices/msp432p4xx/driverlib/driverlib.h> /* Standard Defines */ #include <stdint.h> #include <stdbool.h> #include <string.h> /* Slave Address for I2C Slave */ #define SLAVE_ADDRESS 0x48 #define NUM_OF_REC_BYTES 1 /* Variables */ const uint8_t TXData[] = {0x013,0x007}; static uint8_t RXData; /* I2C Master Configuration Parameter */ const eUSCI_I2C_MasterConfig i2cConfig = { EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 3000000, // SMCLK = 3MHz (default) EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // Desired I2C Clock of 100khz 0, // No byte counter threshold EUSCI_B_I2C_NO_AUTO_STOP // No Autostop }; int main(void) { /* Disabling the Watchdog */ MAP_WDT_A_holdTimer(); /* Select Port 6 for I2C - Set Pin 4, 5 to input Primary Module Function, * (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL). */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN5 + GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN7); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN7); MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN6); MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN6); /* Initializing I2C Master to SMCLK at 100khz with no autostop */ MAP_I2C_initMaster(EUSCI_B1_BASE, &i2cConfig); /* Specify slave address */ MAP_I2C_setSlaveAddress(EUSCI_B1_BASE, SLAVE_ADDRESS); /* Enable I2C Module to start operations */ MAP_I2C_enableModule(EUSCI_B1_BASE); MAP_Interrupt_enableInterrupt(INT_EUSCIB1); // enable RX interrupts MAP_I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT1); while (1) { RXData=0; /* Making sure the last transaction has been completely sent out */ while (MAP_I2C_masterIsStopSent(EUSCI_B1_BASE)); /* Send out EEPROM Mock Read Cmd (2 databytes) */ MAP_I2C_masterSendMultiByteStart(EUSCI_B1_BASE, TXData[1]); // Start + 1Byte MAP_I2C_masterSendMultiByteNext(EUSCI_B1_BASE, TXData[0]); // Poll for TXINT,Send 1Byte /*---------------------------------------------*/ /* Now we need to initiate the read */ /* Wait until 2nd Byte has been output to shift register */ while(!(EUSCI_B1->IFG & EUSCI_B_IFG_TXIFG0)); // Send the restart condition, read one byte, send the stop condition right away EUSCI_B1->CTLW0 &= ~(EUSCI_B_CTLW0_TR); EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTT; while(MAP_I2C_masterIsStartSent(EUSCI_B1_BASE)); EUSCI_B1->CTLW0 |= EUSCI_B_CTLW0_TXSTP; //while(!(EUSCI_B1->IFG & EUSCI_B_IFG_RXIFG0)); //RXData = EUSCI_B0->RXBUF; //--------------------------------- //MAP_PCM_gotoLPM0InterruptSafe(); // Slave should send a single 0x13 back if(RXData != 0x13){ // Error- set P2.7 high MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7); while(1); } __delay_cycles(300000); // ~100ms pause between transmissions } } /******************************************************************************* * eUSCIB0 ISR. The repeated start and transmit/receive operations happen * within this ISR. *******************************************************************************/ void EUSCIB0_IRQHandler(void) { uint_fast16_t status; status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B1_BASE); /* Receives bytes into the receive buffer. If we have received all bytes, * send a STOP condition */ if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT1) { // One-byte Read RXData = MAP_I2C_masterReceiveSingle(EUSCI_B1_BASE); MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2, GPIO_PIN6); } }
I am trying to troubleshoot by probing the interface signals with an oscilloscope, but I am unable to confirm my read or write.
Thanks so much.