IIC communication

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

IIC communication

3,103件の閲覧回数
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 件の賞賛
返信
7 返答(返信)

2,889件の閲覧回数
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 件の賞賛
返信

2,859件の閲覧回数
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 件の賞賛
返信

2,851件の閲覧回数
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 件の賞賛
返信

2,835件の閲覧回数
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 件の賞賛
返信

3,051件の閲覧回数
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 件の賞賛
返信

3,034件の閲覧回数
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 件の賞賛
返信

3,059件の閲覧回数
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 件の賞賛
返信