This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Code Composer Studio
MSP430FR2355 Launchpad is conducting I2C communication test with AT2402 EEPROM.
I wrote the code by referring to the example of i2c driverlib.
It works when you run write operations and read operations on different projects.
EEPROM read sequence = 1byte address write + read data 1byte
The read action does not work after address 1 byte write.
However, if you initial i2c by adding the blue text part, it works normally.
I don't know why.
Do I always have to initial i2c when switching read / write operation?
Please reply.
#include "driverlib.h" #include "Board.h" //***************************************************************************** // //Set the address for slave module. This is a 7-bit address sent in the //following format: //[A6:A5:A4:A3:A2:A1:A0:RS] // //A zero in the "RS" position of the first byte means that the master //transmits (sends) data to the selected slave, and a one in this position //means that the master receives data from the slave. // //***************************************************************************** #define SLAVE_ADDRESS (0xA0 >> 1) //***************************************************************************** // //Specify Expected Receive data count. // //***************************************************************************** #define RXCOUNT 0x01 //***************************************************************************** // //Target frequency for SMCLK in kHz // //***************************************************************************** #define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ 1000 //***************************************************************************** // //SMCLK/FLLRef Ratio // //***************************************************************************** #define CS_SMCLK_FLLREF_RATIO 30 uint8_t RXData; EUSCI_B_I2C_initMasterParam param = {0}; void main (void) { WDT_A_hold(WDT_A_BASE); //Set DCO FLL reference = REFO CS_initClockSignal( CS_FLLREF, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1 ); //Set Ratio and Desired MCLK Frequency and initialize DCO CS_initFLLSettle( CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ, CS_SMCLK_FLLREF_RATIO ); //Set SMCLK = DCO with frequency divider of 1 CS_initClockSignal( CS_SMCLK, CS_DCOCLKDIV_SELECT, CS_CLOCK_DIVIDER_1 ); //Set MCLK = DCO with frequency divider of 1 CS_initClockSignal( CS_MCLK, CS_DCOCLKDIV_SELECT, CS_CLOCK_DIVIDER_1 ); // Configure Pins for I2C /* * Select Port 5 * Set Pin 2, 3 to input with function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL). */ //Set S1 to input direction with internal pull-up resistance GPIO_setAsInputPinWithPullUpResistor( GPIO_PORT_UCB0SCL, GPIO_PIN_UCB0SCL ); GPIO_setAsInputPinWithPullUpResistor( GPIO_PORT_UCB0SDA, GPIO_PIN_UCB0SDA ); // Configure Pins for I2C GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_UCB0SCL, GPIO_PIN_UCB0SCL, GPIO_FUNCTION_UCB0SCL ); GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_UCB0SDA, GPIO_PIN_UCB0SDA, GPIO_FUNCTION_UCB0SDA ); //Set P1.0 as an output pin. /* * Select Port 1 * Set Pin 0 as output */ /* * 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 = RXCOUNT; 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_RECEIVE_MODE 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_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT ); //Enable master Receive interrupt EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT ); EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE, 0x08 ); while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ; while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE)); /* param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = CS_getSMCLK(); param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS; param.byteCounterThreshold = RXCOUNT; param.autoSTOPGeneration = EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD; EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, ¶m); EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE //EUSCI_B_I2C_TRANSMIT_MODE ); //Specify slave address EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS ); EUSCI_B_I2C_enable(EUSCI_B0_BASE); EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT ); //Enable master Receive interrupt EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT ); */ EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE); while (1) { __delay_cycles(2000); // Enter LPM0 w/ interrupt __bis_SR_register(CPUOFF+GIE); } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_B0_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(USCI_B0_VECTOR))) #endif void USCIB0_ISR(void) { static uint8_t count = 0; 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) //EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE); break; case USCI_I2C_UCSTTIFG: // START condition detected with own address (slave mode only) break; case USCI_I2C_UCSTPIFG: // STOP condition detected (master & slave mode) break; case USCI_I2C_UCRXIFG3: // RXIFG3 break; case USCI_I2C_UCTXIFG3: // TXIFG3 break; case USCI_I2C_UCRXIFG2: // RXIFG2 break; case USCI_I2C_UCTXIFG2: // TXIFG2 break; case USCI_I2C_UCRXIFG1: // RXIFG1 break; case USCI_I2C_UCTXIFG1: // TXIFG1 break; case USCI_I2C_UCRXIFG0: // RXIFG0 // Get RX data RXData = EUSCI_B_I2C_masterReceiveSingle( EUSCI_B0_BASE ); if (++count >= RXCOUNT) { count = 0; //EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE); _nop(); _nop(); _nop(); __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; // Vector 24: RXIFG0 break; case USCI_I2C_UCTXIFG0: // TXIFG0 break; case USCI_I2C_UCBCNTIFG: // Byte count limit reached (UCBxTBCNT) GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN0 ); break; case USCI_I2C_UCCLTOIFG: // Clock low timeout - clock held low too long break; case USCI_I2C_UCBIT9IFG: // Generated on 9th bit of a transmit (for debugging) break; default: break; } }
Hi Seunghyun,
What is problems you encounter?
And you can also use this register level example code to debug:
https://dev.ti.com/tirex/explore/node?node=APY73Ag8ABgSCUJ2J7EVtw__IOGqZri__LATEST
Thanks!
Best Regards
Johnson
**Attention** This is a public forum