IIC communication

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IIC communication

3,102 Views
NandithaR
Contributor I

There was an acknowledgement issue for the example code of I2C provided for MPC5748G.Is the I2C_2 module configured as slave within the microcontroller or an external slave,also how to get the address of slave.Is there any other factors other than the slave address that can lead to this no acknowledgement.

0 Kudos
Reply
7 Replies

2,888 Views
NandithaR
Contributor I

When I2C0 is configured as master ,while trying to write 1 to MSSL it is not setting to one 1 .What might be the reason for that?

0 Kudos
Reply

2,858 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

share the code you have. The demo (I2C 1 to I2C2) you mentioned is working well, so I2C0 should work similarly. Be sure pins are properly initialized and bus have pull ups.

BR, Petr

0 Kudos
Reply

2,850 Views
NandithaR
Contributor I
Given below is the code :Here we are trying to write to an external EEPROM M24512-DRE.

//#include "i2c.h"
#include "I2C_0.h"
#include "derivative.h" /* include peripheral declarations */
#include "project.h"
#include "mode.h"
//#include<MPC5748G.h>





void initI2C_0(void) { /* I2C0 module configured as a Master and in Transmit mode */
//I2C_0 SDA SIGNAL
SIUL2.MSCR[PO0].B.OBE = 1;
SIUL2.MSCR[PO0].B.ODE = 1;
SIUL2.MSCR[PO0].B.IBE = 1;
SIUL2.MSCR[PO0].B.PUS = 1;
SIUL2.MSCR[PO0].B.PUE = 1;
SIUL2.MSCR[PO0].B.SSS = 2;
SIUL2.IMCR[266].B.SSS = 3;



//I2C_0 SCL SIGNAL
SIUL2.MSCR[PO1].B.OBE = 1;
SIUL2.MSCR[PO1].B.ODE = 1;
SIUL2.MSCR[PO1].B.IBE = 1;
SIUL2.MSCR[PO1].B.PUS = 1;
SIUL2.MSCR[PO1].B.PUE = 1;
SIUL2.MSCR[PO1].B.SSS = 2;
SIUL2.IMCR[265].B.SSS =3;





I2C_0.IBFD.B.IBC = 0x20; /* Division ratio to obtain SCL frequency from Platform clock/2. */





//I2C_0.IBAD.R = 0X00; /* Address of slave is 0 */;



I2C_0.IBCR.B.MDIS = 0; /* I2C module is enabled */
I2C_0.IBCR.B.IBIE = 0; /* Interrupt disabled */

I2C_0.IBCR.B.TXRX = 1; /* Transmits Data */





I2C_0.IBSR.R = 0x12; // Clear the IBAL, IBIF flags;



}





tI2C_0_fault I2C_0_WriteBlock(uint8_t dev_addr, uint16_t reg_addr, uint8_t reg_addr_nBytes, uint8_t *pData, uint8_t nBytes)
{
if(I2C_0_Res_flg==I2C_0_FLAG_NONE)
{
I2C_0_Dev_Addr = dev_addr; // address to select a slave
I2C_0_Addr = reg_addr; // slave register/memory address to be written
pI2C_0_Data = pData; // pointer to data to be written
I2C_0_nBytes = nBytes; // number of bytes to be written



if(I2C_0.IBSR.B.IBB==1) // check if bus is busy
{
I2C_0_fault = I2C_0_BUS_BUSY;
return(I2C_0_fault);
}



if(reg_addr_nBytes==2) I2C_0_stage = I2C_0_STAGE_WRITE_REG_ADDRESS_HIGH;
if(reg_addr_nBytes==1) I2C_0_stage = I2C_0_STAGE_WRITE_REG_ADDRESS_LOW;



I2C_0_mode = I2C_0_MODE_WRITE;



I2C_0_Res_flg = I2C_0_FLAG_TRANSMISSION_PROGRESS;
I2C_0_fault = I2C_0_FRAME_NO_ENDED;



I2C_0.IBCR.B.MSSL = 1; // Set transmit and master mode
I2C_0.IBCR.B.TXRX= 1; // And generate start condition
I2C_0.IBSR.R = 0x12; // Clear the IBAL, IBIF flags;



I2C_0.IBDR.R = I2C_0_Dev_Addr; // Send device address



if(I2C_0.IBCR.B.IBIE == 0) // if interrupt is not used
{
while(I2C_0_Res_flg==I2C_0_FLAG_TRANSMISSION_PROGRESS)
{
while (I2C_0.IBSR.B.IBIF==0){}; // Wait until IBIF;
I2C_0_Callback();
}
}
}



if(I2C_0_Res_flg==I2C_0_FLAG_TRANSMISSION_COMPLETE)
{
I2C_0_Res_flg=I2C_0_FLAG_NONE;
I2C_0_fault = I2C_0_NO_FAULT;



if(I2C_0_stage==I2C_0_STAGE_NAK) I2C_0_fault = I2C_0_NO_ACK;
if(I2C_0_stage==I2C_0_STAGE_ARBITRATION_LOST) I2C_0_fault = I2C_0_ARBITRATION_LOST;
}



return(I2C_0_fault);



}



tI2C_0_fault I2C_0_ReadBlock_defined_addr(uint8_t dev_addr, uint16_t reg_addr,
uint8_t reg_addr_nBytes, uint8_t *pData, uint8_t nBytes)
{



if(I2C_0_Res_flg==I2C_0_FLAG_NONE)
{
I2C_0_Dev_Addr = dev_addr; // address to select a slave
I2C_0_Addr = reg_addr; // slave register/memory address to be read
pI2C_0_Data = pData; // pointer to data buffer to be filled
I2C_0_nBytes = nBytes; // number of bytes to be read



if(I2C_0.IBSR.B.IBB==1) // check if bus is busy
{
I2C_0_fault = I2C_0_BUS_BUSY;
return(I2C_0_fault);
}



if(reg_addr_nBytes==2) I2C_0_stage = I2C_0_STAGE_WRITE_REG_ADDRESS_HIGH;
if(reg_addr_nBytes==1) I2C_0_stage = I2C_0_STAGE_WRITE_REG_ADDRESS_LOW;



I2C_0_mode = I2C_0_MODE_READ;



I2C_0_Res_flg = I2C_0_FLAG_TRANSMISSION_PROGRESS;
I2C_0_fault = I2C_0_FRAME_NO_ENDED;



I2C_0.IBCR.B.MSSL = 1; // Set transmit and master mode
I2C_0.IBCR.B.TXRX = 1; // And generate start condition



I2C_0.IBDR.R = I2C_0_Dev_Addr; // Send device address



if(I2C_0.IBCR.B.IBIE == 0) // if interrupt is not used
{
while(I2C_0_Res_flg==I2C_0_FLAG_TRANSMISSION_PROGRESS)
{
while (I2C_0.IBSR.B.IBIF==0){}; // Wait until IBIF;
I2C_0_Callback();
}
}
}



if(I2C_0_Res_flg==I2C_0_FLAG_TRANSMISSION_COMPLETE)
{
I2C_0_Res_flg=I2C_0_FLAG_NONE;
I2C_0_fault = I2C_0_NO_FAULT;



if(I2C_0_stage==I2C_0_STAGE_NAK) I2C_0_fault = I2C_0_NO_ACK;
if(I2C_0_stage==I2C_0_STAGE_ARBITRATION_LOST) I2C_0_fault = I2C_0_ARBITRATION_LOST;
}



return(I2C_0_fault);
}



void I2C_0_Callback(void)
{
uint8_t dummy;
uint8_t status;



status = I2C_0.IBSR.R;



if(I2C_0.IBCR.B.MSSL) // if master mode
{
if(I2C_0.IBCR.B.TXRX) // if TX
{
if((status&1)==0) // if ACK received, RXAK == 0
{
switch(I2C_0_stage)
{
case I2C_0_STAGE_WRITE_REG_ADDRESS_HIGH:
{
I2C_0.IBDR.R = I2C_0_Addr_H; // Send upper byte of word address;
I2C_0_stage = I2C_0_STAGE_WRITE_REG_ADDRESS_LOW;
}
break;
case I2C_0_STAGE_WRITE_REG_ADDRESS_LOW:
{
I2C_0.IBDR.R = I2C_0_Addr_L; // Send lower byte of word address;



if(I2C_0_mode==0) I2C_0_stage = I2C_0_STAGE_WRITE_DATA;
else I2C_0_stage = I2C_0_STAGE_REPEATED_START;
}
break;



case I2C_0_STAGE_REPEATED_START:
{
I2C_0.IBCR.B.RSTA = 1; // generate repeated START
I2C_0.IBDR.R = I2C_0_Dev_Addr | 1; // Send byte Control
I2C_0_stage = I2C_0_STAGE_READ_DUMMY_DATA;
}
break;
case I2C_0_STAGE_READ_DUMMY_DATA:
{
I2C_0.IBCR.B.TXRX = 0; // set for receive
if(I2C_0_nBytes==1) I2C_0.IBCR.B.NOACK = 1; // if just 1 byte is going to be read
// NOACK next received byte



dummy = I2C_0.IBDR.R; // initiates next byte data receiving
}
break;
case I2C_0_STAGE_WRITE_DATA:
{
if(I2C_0_nBytes) // if not last byte TXed
{
I2C_0.IBDR.R = *pI2C_0_Data++; // write data;
I2C_0_nBytes--;
}
else // last byte TXed
{
I2C_0.IBCR.B.MSSL = 0; // Generate stop signal;
I2C_0_stage = I2C_0_STAGE_NONE;
I2C_0_Res_flg = I2C_0_FLAG_TRANSMISSION_COMPLETE; // end of I2C transfer
}
}
break;



}
}
else
{
// byte not ACKed
I2C_0.IBCR.B.MSSL = 0; // Generate stop signal;
I2C_0_stage = I2C_0_STAGE_NAK;
I2C_0_Res_flg = I2C_0_FLAG_TRANSMISSION_COMPLETE;
}





}
else // if RX
{
if((I2C_0_nBytes-2)==0)
{
I2C_0.IBCR.B.NOACK = 1; // NOACK next received byte
}
if((I2C_0_nBytes-1)==0)
{
I2C_0.IBCR.B.MSSL = 0; // Set IBCR, Generate stop signal;
I2C_0.IBCR.B.NOACK = 0; // Reset the NOACK to default value
I2C_0_stage = I2C_0_STAGE_NONE;
I2C_0_Res_flg = I2C_0_FLAG_TRANSMISSION_COMPLETE; // end of I2C transfer
}



*(pI2C_0_Data++) = I2C_0.IBDR.R; // Read the received byte from slave



I2C_0_nBytes--;
}
}
else // if slave mode
{
if(status&0x10) // if IBAL bit is set
{
I2C_0_stage = I2C_0_STAGE_ARBITRATION_LOST;
I2C_0_Res_flg = I2C_0_FLAG_TRANSMISSION_COMPLETE; // end of I2C transfer
I2C_0.IBSR.R = 0x10; // clear IBAL flag
}
}



I2C_0.IBSR.R = 0x2; // clear IBIF flag



}



0 Kudos
Reply

2,834 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

I do not have right board now to test I2C0 on PO0/1 pins.
Once you write MSSL what is a value read from IBSR?
Maybe MSSL is cleared due to lose of arbitration.
Can you measure SDA/SCL lines at this time?

BR, Petr

0 Kudos
Reply

3,050 Views
NandithaR
Contributor I
Given below is the example code used
 
#include "derivative.h" /* include peripheral declarations */
#include "project.h"
#include "mode.h"
#include "i2c.h"
 
 
#define KEY_VALUE1 0x5AF0ul
#define KEY_VALUE2 0xA50Ful
 
extern void xcptn_xmpl(void);
void peri_clock_gating(void); /* Configure gating/enabling peripheral(I2C) clocks */
 
void hw_init(void)
{
#if defined(DEBUG_SECONDARY_CORES)
uint32_t mctl = MC_ME.MCTL.R;
#if defined(TURN_ON_CPU1)
/* enable core 1 in all modes */
MC_ME.CCTL[2].R = 0x00FE;
/* Set Start address for core 1: Will reset and start */
MC_ME.CADDR[2].R = 0x11d0000 | 0x1;
#endif
#if defined(TURN_ON_CPU2)
/* enable core 2 in all modes */
MC_ME.CCTL[3].R = 0x00FE;
/* Set Start address for core 2: Will reset and start */
MC_ME.CADDR[3].R = 0x13a0000 | 0x1;
#endif
MC_ME.MCTL.R = (mctl & 0xffff0000ul) | KEY_VALUE1;
MC_ME.MCTL.R =  mctl; /* key value 2 always from MCTL */
#endif /* defined(DEBUG_SECONDARY_CORES) */
}
 
/************************************ Main ***********************************/
 
__attribute__ ((section(".text")))
int main(void)
{
uint8_t data;
 
xcptn_xmpl ();              /* Configure and Enable Interrupts */
 
peri_clock_gating(); /* Configure gating/enabling peripheral(I2C) clocks */
system160mhz();
    /* Sets clock dividers= max freq,
       calls PLL_160MHz function which:
       MC_ME.ME: enables all modes for Mode Entry module
       Connects XOSC to PLL
       PLLDIG: LOLIE=1, PLLCAL3=0x09C3_C000, no sigma delta, 160MHz
       MC_ME.DRUN_MC: configures sysclk = PLL
       Mode transition: re-enters DRUN which activates PLL=sysclk & peri clks
       */
initI2C_1(); /* I2C1 module configured as a Master and in Transmit mode */
initI2C_2(); /* I2C2 module configured as a Slave and in Receive mode */
 
/* Transmit Address */
transmit_addr_master_I2C_1(0xFE);
receive_addr_slave_I2C_2();
 
while(1)
{
transmit_data_master_I2C_1('H');
data = receive_data_slave_I2C_2();
if(data == 'H')
{
SIUL2.MSCR[PA10].B.OBE ^= 1;  /* Pad PA10 (10): OBE=OBE xor 1. On EVB active low DS4 LED */
data = 0;
}
}
return 0;
}
 
/********************  End of Main ***************************************/
 
void peri_clock_gating() { /* Configure gating/enabling peripheral(I2C) clocks */
MC_ME.RUN_PC[0].R = 0x00000000;  /* Gate off clock for all RUN modes */
MC_ME.RUN_PC[1].R = 0x000000FE;  /* Configures peripheral clock for all RUN modes */
MC_ME.PCTL[31].B.RUN_CFG = 0x1;  /* I2C_1: select peripheral configuration RUN_PC[1] */
MC_ME.PCTL[32].B.RUN_CFG = 0x1;  /* I2C_2: select peripheral configuration RUN_PC[1] */
}

 

0 Kudos
Reply

3,033 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

with below pin setting and EVB connection mentioned in the example the communication is done

2023-10-05_12-09-42.png

 

Instead of internal weak pull-ups I selected, an external pull-ups should be used as mentioned in the example.

BR, Petr

0 Kudos
Reply

3,058 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

could you please point to the example you are using? If MPC5748G is configured as slave then its address is specified by IBAD register. If it is master then slave address is sent by user, when addressing a slave. So be sure correct address is sent over I2C bus. Also check if bus is properly pulled-up.

BR, Petr

0 Kudos
Reply