I was trying to create project which use I2C protocol to control multiple node. When I am trying to control only one node address on the bus, my code works perfectly, but when I tried to talk with two nodes, only first command work on all over the system. This is my driver using keil IDE and tiva c < TM4C123GH6PM >
#include "I2C.h"
/********************* Functions *************************/
void i2c0Enable(i2cState state)
{
/*************** enable I2C configuration ****************/
/* enable I2C clock */
SYSCTL->RCGCI2C |=(1 << 0 ); // true
/* enable portB clock */
SYSCTL->RCGCGPIO |= (1 << 1 ); //true
/* configure alternative function registser of portB to work as I2C */
//GPIOB->AFSEL &=~((1 << 2 ) | (1 << 3 ));
GPIOB->AFSEL |=((1 << 2 ) | (1 << 3 )); //true
/* enable digital */
//GPIOB->DEN &= ~((1 << 2 ) | ( 1 << 3 ));
GPIOB->DEN |= ((1 << 2 ) | ( 1 << 3 )); //true
/* enable open drain on pin3 of portB (SDL) */
GPIOB->ODR |=(1 << 3) ; //true
/* disable pullup and pull down */
//GPIOB->PUR &=~((1 << 2 ) | (1 << 3 )); // not needed
/* disable puldown resistance */
//GPIOB->PDR &=~((1 << 2 ) | (1 << 3 )); // not needed
/* configure pin[2,3] of portB to work as SDL,SCL */
GPIOB->PCTL |= ( 0x3 << 12 ) | (0x3 << 8) ; // true
/* configure GPIOCR register to let other settings to take effect */
//GPIOB->CR |= ( 1 <<3 ) | (1 << 2) ; // deleted if any error
/*******************************************************/
/* configure bus speed depending on i2c state*/
/* all the calculations are depending one the equation */
/* TPR = (System Clock/(2*(SCL_LP + SCL_HP)*SCL_CLK))-1; */
/* where SCL_LP and SCL_HP are fixed to the values 4 and 6 respectivelly */
/* and the HS bit in I2CMTPR register is 0 for all modes but high speed mode */
switch(state)
{
case STANDARD :
/* speed is 100kbps */
I2C0->MTPR = (SystemCoreClock / (2000000))-1 ;
break;
case FAST :
/* speed is 400kbps */
I2C0->MTPR = (SystemCoreClock / (8000000))-1 ;
break;
case FASTPLUS :
/* speed is 1Mbps */
I2C0->MTPR = (SystemCoreClock / (20000000))-1 ;
break;
case HIGHSPEED :
/* speed is 3.33Mbps */
I2C0->MTPR = (SystemCoreClock / (19980000))-1 ;
/* setting HS bit in both registers to run in high speed mode */
I2C0->MTPR |= (1 << 7 ) ;
setBit(I2C0->MCS , BIT4) ;
break;
}
}
master sending function
void i2cSendMaster(uint8_t data,uint8_t slaveAddress)
{
/* Initialize the I2C Master by writing the I2CMCR register with */
/* a value of 0x0000.0010 */
I2C0->MCR |=(1 << 4) ; // true
/* setting speed to standard mode */
//I2C0->MTPR = 7 ; // true
/* applying master slave address with default write operation */
I2C0 ->MSA |=(slaveAddress << 1 ); //true
I2C0 ->MSA &=~(1 << 0 ); // true
I2C0 -> MDR = data ; //true
/* check BUSBSY bit to confirm that bus is free to write on */
// while( (I2C0->MCS & (1 << 6)) != 0 ) ;
/*Initiate a single byte transmit of the data from Master to Slave by writing the I2CMCS register
with a value of 0x0000.0007 (STOP, START, RUN).*/
I2C0 -> MCS = 7 ; // true <<<<
/* checking Bus busy bit to check if the transmission is complete*/
//while( (I2C0->MCS & (0x00000040)) == 1 ) ; ///
while( (I2C0->MCS & (1 << 0)) == 1 ) ; // true ( check contoller buzzy state )
/* new code */
/* check if data sent with errors */
if((I2C0->MCS & (1 << 1)) == 1 )
{
SYSCTL ->RCGCGPIO |=(1 << 5 );
GPIOF ->DEN |=((1 << 1) | ( 1 << 2 ) | (1 << 3 ));
GPIOF ->DIR |=((1 << 1) | ( 1 << 2 ) | (1 << 3 ));
GPIOF ->DATA |=(1 << 1) ;
}
else
{
SYSCTL ->RCGCGPIO |=(1 << 5 );
GPIOF ->DEN |=((1 << 1) | ( 1 << 2 ) | (1 << 3 ));
GPIOF ->DIR |=((1 << 1) | ( 1 << 2 ) | (1 << 3 ));
GPIOF ->DATA |=(1 << 3) ;
}
}
slave receive code
uint8_t i2cSlaveReceive(void)
{
uint8_t data ;
/* Initialize the I2C Slave by writing the I2CMCR register with */
/* a value of 0x0000.0010 */
/* set SFE bit ; */
I2C0->MCR = 0x20 ;
/* set slave own address */
I2C0 ->SOAR = 0x3b ;
/* enable slave operation */
setBit(I2C0->SCSR , BIT0 ) ;
/* check if any valid data received */
while((I2C0->SRIS & (1 << BIT0 )) != 1);
// while(!checkBit(I2C0 ->SRIS,BIT0 ));
/* receive data */
data = I2C0->SDR ;
/* set enable acknowledge with NACK in response */
//setBit(I2C0 ->SACKCTL , BIT0 );
//setBit(I2C0 ->SACKCTL , BIT1 );
/* clearing received data flag */
setBit(I2C0 ->SICR , BIT0 );
/* returning data received */
return data ;
}
User contributions licensed under CC BY-SA 3.0