Other Parts Discussed in Thread: MSPM0G3507, SYSCONFIG
Tool/software:
Hi,
Can we transmit data from one I2C port to another I2C port within the same controller?
Launchpad which I am using is: MSPM0G3507
Thank you
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:
Hi,
Can we transmit data from one I2C port to another I2C port within the same controller?
Launchpad which I am using is: MSPM0G3507
Thank you
Hi Tejal,
Sure. You could set one I2C as controller and another as slave and just connect SCL and SDA pin together.
Do I also need to connect pull-up resistors for I2C communication? and could you provide a simple sample code for setting up I2C communication.
Thank you,
Tejal
Hi Tejal,
Yes, you could either use the internal pull-up resistors or external pull-up resistors.
As for example, you could merge the i2c controller and target example into one project for you application. The interrupt example could be used for i2c target.

Hi Pengfei,
I tried merging the I2C controller and target example, but I am not getting an acknowledgment from the target device. I am also attaching the output which I observed on the logic analyzer.
Thank you,
Tejal
Which examples did you merge? I expect you'd want to use an interrupt-driven model on the target side.
Did you change the target I2C address on both sides?
Yes I changed the I2C address on both side and also, I am using interrupt driven code on target side, and following 2 examples I merged:
1) i2c_controller_multibyte_fifo_poll and 2) i2c_target_multibyte_fifo_interrupt
Hi Tejal,
It is correct that you are using the interrupt example for I2C target.
There are some items you could check:
Best Regards,
Pengfei
Can you post your resulting (merged) code? Sometimes all it takes is a typo.
----------------
For the target side, the contents of main() should be suitable for a "target_init()" function, except for:
DL_SYSCTL_enableSleepOnExit();
This should be removed, since it has a global effect on the program. (It could produce the symptom you're seeing.)
while (1) {
__WFI();
}
This should be removed. (I'm guessing you already did this one.)
Thank you for your feedback. I have made the necessary adjustments to the code as per your suggestions. I am attaching the updated code for your review. Could you please check the resulting (merged) code?
#include <ti/driverlib/m0p/dl_interrupt.h>
#include "ti_msp_dl_config.h"
#define I2C_TX_PACKET_SIZE (8)
#define I2C_RX_PACKET_SIZE (5)
#define I2C_TX_MAX_PACKET_SIZE (16)
#define I2C_RX_MAX_PACKET_SIZE (16)
uint8_t gTxPacket[I2C_TX_PACKET_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
volatile uint8_t gRxPacket[I2C_RX_PACKET_SIZE];
uint32_t gTxLen, gTxCount;
/* Data sent to Controller in response to Read transfer */
uint8_t gTxPacket1[I2C_TX_MAX_PACKET_SIZE] = {0x00};
volatile uint8_t gRxPacket1[I2C_RX_MAX_PACKET_SIZE];
uint32_t gRxLen, gRxCount;
int main(void)
{
SYSCFG_DL_init();
gTxCount = 0;
gTxLen = I2C_TX_MAX_PACKET_SIZE;
DL_I2C_enableInterrupt(I2C_1_INST, DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER);
/* Initialize variables to receive data inside RX ISR */
gRxCount = 0;
gRxLen = I2C_RX_MAX_PACKET_SIZE;
DL_I2C_fillControllerTXFIFO(I2C_0_INST, &gTxPacket[0], I2C_TX_PACKET_SIZE);
/* Wait for I2C to be Idle */
while (!(
DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
;
DL_I2C_startControllerTransfer(I2C_0_INST, I2C_1_TARGET_OWN_ADDR,
DL_I2C_CONTROLLER_DIRECTION_TX, I2C_TX_PACKET_SIZE);
/* Poll until the Controller writes all bytes */
while (DL_I2C_getControllerStatus(I2C_0_INST) &
DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
;
/* Trap if there was an error */
if (DL_I2C_getControllerStatus(I2C_0_INST) &
DL_I2C_CONTROLLER_STATUS_ERROR) {
/* LED will remain high if there is an error */
__BKPT(0);
}
/* Wait for I2C to be Idle */
while (!(
DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE))
;
/* Add delay between transfers */
delay_cycles(1000);
DL_I2C_startControllerTransfer(I2C_0_INST, I2C_1_TARGET_OWN_ADDR,
DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE);
for (uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) {
while (DL_I2C_isControllerRXFIFOEmpty(I2C_0_INST));
gRxPacket[i] = DL_I2C_receiveControllerData(I2C_0_INST);
}
while (1) {
}
}
void I2C_1_INST_IRQHandler(void)
{
static bool dataRx = false;
switch (DL_I2C_getPendingInterrupt(I2C_1_INST)) {
case DL_I2C_IIDX_TARGET_START:
/* Initialize RX or TX after Start condition is received */
gTxCount = 0;
gRxCount = 0;
dataRx = false;
/* Flush TX FIFO to refill it */
DL_I2C_flushTargetTXFIFO(I2C_1_INST);
break;
case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
/* Store received data in buffer */
dataRx = true;
while (DL_I2C_isTargetRXFIFOEmpty(I2C_1_INST) != true) {
if (gRxCount < gRxLen) {
gRxPacket1[gRxCount++] = DL_I2C_receiveTargetData(I2C_1_INST);
} else {
/* Prevent overflow and just ignore data */
DL_I2C_receiveTargetData(I2C_1_INST);
}
}
break;
case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
/* Fill TX FIFO if there are more bytes to send */
if (gTxCount < gTxLen) {
gTxCount += DL_I2C_fillTargetTXFIFO(
I2C_1_INST, &gTxPacket1[gTxCount], (gTxLen - gTxCount));
} else {
while (DL_I2C_transmitTargetDataCheck(I2C_1_INST, 0x00) != false)
;
}
break;
case DL_I2C_IIDX_TARGET_STOP:
/* If data was received, echo to TX buffer */
if (dataRx == true) {
for (uint16_t i = 0;
(i < gRxCount) && (i < I2C_TX_MAX_PACKET_SIZE); i++) {
gTxPacket1[i] = gRxPacket1[i];
DL_I2C_flushTargetTXFIFO(I2C_1_INST);
}
dataRx = false;
}
break;
default:
break;
}
}> DL_I2C_enableInterrupt(I2C_1_INST, DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER);
After this, I think you need additionally (I'm guessing at the IRQN name):
> NVIC_EnableIRQ(I2C_1_IRQN); // Enable Target interrupt in NVIC
----------
But this wouldn't result in a NACK. I wonder if the I2C_1 (target) setup in ti_msp_dl_config.c is missing a call to:
> DL_I2C_setTargetOwnAddress(I2C_1_INST, I2C_1_TARGET_OWN_ADDR);
This is generated by sysconfig in the Example, but maybe it got lost in the merge?
----------
More generally, it seems that you're using the same Tx/Rx buffers for both sides. Maybe you've checked that it works OK, but it seems hazardous at first glance.