Other Parts Discussed in Thread: LP5569, MSP430FR2476
I am having trouble establishing multi-byte, interrupt-driven I2C communication from my MSP430FR2476 (master) to my LP5569 (slave) LED driver. I have followed the examples to setup some skeleton code, and I just want to write two bytes to the LP5569. Namely, I need to send it a control register address, and data to write to that control register. I am using 0x40 for the value of the slave address.
Here is a rough sketch of what I am trying to do:
#include "driverlib.h" #include <msp430fr2476.h> #define SLAVE_ADDRESS 0x40 // Pointer to TX data uint8_t TXData = 0; uint8_t TXByteCtr; void main(void) { WDT_A_hold(WDT_A_BASE); // Configure Pins for I2C GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P1, GPIO_PIN2 + GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION ); /* * Disable the GPIO power-on default high-impedance mode to activate * previously configured port settings */ PMM_unlockLPM5(); EUSCI_B_I2C_initMasterParam param = {0}; param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = CS_getSMCLK(); param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS; param.byteCounterThreshold = 0; param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP; EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, ¶m); //Specify slave address EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS ); //Set Master in receive mode EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE ); //Enable I2C Module to start operations EUSCI_B_I2C_enable(EUSCI_B0_BASE); EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT ); //Enable master Receive interrupt EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT ); EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, 0x40); for(;;) } //------------------------------------------------------------------------------ // The USCIAB0TX_ISR is structured such that it can be used to transmit any // number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData // points to the next byte to transmit. //------------------------------------------------------------------------------ #pragma vector=USCI_B0_VECTOR __interrupt void USCIB0_ISR(void) { switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)) { case USCI_NONE: // No interrupts break; break; case USCI_I2C_UCALIFG: // Arbitration lost break; case USCI_I2C_UCNACKIFG: // NAK received (master only) //resend start if NACK EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE); break; case USCI_I2C_UCTXIFG0: // TXIFG0 // Check TX byte counter // Not reaching this point EUSCI_B_I2C_masterSendNextByte(EUSCI_B0_BASE, 0x40); break; default: break; } }
The code hangs before it gets to any interrupt code. Within the multi-byte start call in eusci_b_i2c.c, the program hangs on the following line in EUSCI_B_I2C_masterSendMultiByteStart():
//Poll for transmit interrupt flag.
while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
I am also curious about what the best way to troubleshoot this problem is. I am following the driverlib's User Guide to configure the I2C module, and the GPIO pins are definitely setup properly. I have been walking through the program, and it looks like all the interrupt flags are set up properly. Any advice is greatly appreciated! Thanks in advance.