1,767 Views 3 Replies Last post: Aug 9, 2009 2:30 AM by Nrapl RSS
Nrapl Newbie 5 posts since
Jun 15, 2009
Currently Being Moderated

Jun 15, 2009 11:12 PM

Problem with UART0 in I2C mode

Hello,

    I am using R32C/111(r5f64112) with HEW environment.

    I want to communicate with AT24C08A EEPROM with uart0 (in i2c mode).

    For that the code written is as follows:

    But i can't understand where is the problem.Do i2c protocol for both matches or not?or else i have to take any other precaution.

   Becoz i can see data on SDA & SCL pins without checking ACK.But if i check ACK,after START condition also EEPROM doesn't give acknowledgment.

   Why this is happening.

  

                 
#include "sfr111.h"     
#define plc_reg  (volatile)plc

#define  Delay  for(i=0;i<15000;i++);  // delay to i2c bits
#define Delay2  1000000
#define Enable_IRQ    {_asm(" FSET I");}

void SetPLLClock(void);
void EEPROM_byte_read(unsigned char addr,unsigned char* data);
void EEPROM_byte_write(unsigned char addr, unsigned char data);
char EEPROM_send_data(unsigned char data);
void i2c_start(void);
void i2c_restart(void);
void i2c_stop(void);
void i2c_enable_rx(void);
void i2c_init(void);

void
main(void)
{
    int blnk=Delay2, flg=0,i;

  unsigned char read_data=0,write_data=0x06;
 
SetPLLClock();
 
  asm("FCLR I") ;                     // (1) Interruption inhibition
 
  pd2=0xff; pd3=0xff; pd4=0xff; pd5=0xff;
  pd7=0xff; pd8=0xdf;
 
  i2c_init();

  read_data=0x06;
  p10_3=1;
    

       EEPROM_byte_read(0x00,&read_data);
 
       p0=write_data;
       p1=read_data;
 
  if(write_data==read_data)
    {
     do
     {    
       if(flg==0)
         {
        blnk--;
        if(blnk==0)
          {
          flg=1;
              p10_3=0;
                 }
      }
    else
       {
       blnk++;
        if(blnk==Delay2)
         {
        flg=0;    
              p10_3=1;
                  
         }
      }
      }while(1);
     
    }

       
  }

/*""FUNC COMMENT""***************************************************
* Outline              : A set of Main Clock
* Description          : A set of Main Clock
*                      : XIN              16MHz
*                      : PLL Clock        100MHz
*                      : Base Clock       50MHz
*                      : CPU Clock        50MHz
*                      : Bus Clock        25MHz
*                      : Peripheral Clock 16.66MHz
* Argument             : none
* Return Value         : none
*""FUNC COMMENT END""**********************************************/

void SetPLLClock(void)
{
/*  int count=50000;
  
   prc1=1;
   pm0=0x80;  //select single chip mode.
   pm2=0x02;
   prc1=0;
    
   prr=0xAA;
   pbc=0x2504;
   ccr=0x0F;   //set PLL clock frequency to 100MHz.
   ccr=ccr | 0x10;  
   prr=0;
 
   prc0=1;
   cm0=0x40;
   cm1=0x20;
   cm2=0;
   pm3=0x20;
   prc0=0;
 
   prc2=1;
   plc0=0x05;
  
   prc2=1;
   plc1=0x02;  
  
    prc2=1;
    pd9=0xf8;
   
   while(count > 0) count--;
 
   tcspr=0x00;
   cpsrf=0x00;*/
   unsigned char tmp = 0x00 ;
    unsigned int i;

    prc1 = 0x01 ;                       // Write enabled PM2
    tmp = pm2 ;                         //     f2n Count Source Select Bit : Main clock
    tmp |= 0x40 ;                       //
    tmp &= 0x52 ;                       //
    pm2 = tmp ;                         //
    prc1 = 0x00 ;                       //     Write disabled PM2

    tcspr = 0x00 ;                      // (4) Stop divider operation
    tcspr = 0x00 ;                      //     The clock is not divided
    tcspr = 0x80 ;                      //     Start divided operation

    prc2 = 0x01 ;                       // (6) Write enabled plc0
    plc0 = 0x04 ;                       //     A setup of PLL Clock(100MHz)
    prc2 = 0x01 ;                       //     Write enabled plc1
    plc1 = 0x03 ;                       //     Self-oscillation mode -> PLL mode

     Delay   //for stabilizing PLL clock.

    tmp = tcspr ;                       // (10)Stop divider operation
    tmp &= 0x0f ;                       //
    tcspr = tmp ;                       //

    prc1 = 0x01 ;                       // (11)Write enabled PM2
    tmp = pm2 ;                         //     f2n Count Source Select Bit :Peripheral clock source
    tmp &= 0x12 ;                       //
    pm2 = tmp ;                         //
    prc1 = 0x00 ;                       //     Write disabled PM2

    prr = 0xAA ;                        // (12)Write enabled CCR,PBC
    tmp = pbch ;                        //     A setup of Peripheral Bus Timing
    tmp |= 0x05 ;                       //     Peripheral Bus Clock Divided Ratio :Divided-by-2(25MHz)
    tmp &= 0x65 ;                       //
    pbch = tmp ;                        //
    pbcl = 0x04 ;                       //

    ccr = 0x1f ;                        // (13)Peripheral Bus Clock Divided Ratio :Divided-by-2(25MHz)
                                        //     CPU Clock Divided Ratio :No division(50MHz)
                                        //     Base Clock Divided Ratio :Divided-by-2(50MHz)
                                        //
    prr = 0x00 ;                        //     Write disabled CCR,PBC

    prc0 = 0x01 ;                       // (14) Write enabled PM3
    pm3 = 0x20 ;                        //      Peripheral Clock Source Divided Ratio ivided-by-6(16.66MHz)
    prc0 = 0x00 ;                       //      Write disabled PM3
 
}
//--------------------------------------------------------------------------------------
// Name:  EEPROM_byte_read
// Parameters: Address (byte) & variable in which to read(byte)
// Returns: None
// Description: It reads a byte in the pointed memory position
//--------------------------------------------------------------------------------------
void
EEPROM_byte_read(unsigned char addr,unsigned char* data)
{
unsigned char error,address,aux;

aux=10;

u0tbh = 0x01;    //for sending NACK at 9th clock cycle.
i2c_enable_rx();          //enable transmission & reception.

i2c_start();
 
   do
  {
  if (EEPROM_send_data(0xA0) == 0)    //send device address until communication is established.
   { 
    aux = 0;
    error = 0;
   }
   else  aux--;
  } while (aux != 0);
  
    error=1;    
  

 

     if(EEPROM_send_data(addr)==0)
  error=0;
 
    
  i2c_start();
 
if(error==0)
    {
       error=1;
       if (EEPROM_send_data(0xA1) == 0)
           error = 0;
    }
    
if(error==0)    
       EEPROM_send_data(0xFF); // dummy write

   i2c_stop();

*data = u0rbl;

}

 

//--------------------------------------------------------------------------------------
// Name:  EEPROM_send_data
// Parameters: Byte to be sent
// Returns: 1 = NACK received, 0 = ACK received
// Description: Send a byte through the serial line
//--------------------------------------------------------------------------------------
char EEPROM_send_data(unsigned char data)
{
  int i;
  static char c=0;
 
te_u0c1 = 1;    // transmit data (enable bit)

while(!ti_u0c1);   // wait for tx buffer to be empty

u0tbl = data;    // transmit data

while((!ir_s0ric) && (!ir_s0tic)); // wait until ack or nack

   te_u0c1 = 0;    // disable transmission

   if ((u0rbh & 0x01) == 1)
    {return(1); }
   else
       {return(0);}
}

//--------------------------------------------------------------------------------------
// Name:  i2c_start
// Parameters: None
// Returns: None
// Description: Generates the start condition in the i2c line
//--------------------------------------------------------------------------------------
void
i2c_start(void)
{  
unsigned int i;

    iicm_u0smr =1;
//Delay
stareq_u0smr4 = 1;   // Start condition generate bit
//Delay
    stspsel_u0smr4 = 1;  // SCL, SDA output select bit - set
Delay
stspsel_u0smr4 = 0;  // SCL, SDA output select bit - reset

    while(stareq_u0smr4==1);

  }


//--------------------------------------------------------------------------------------
// Name:  i2c_stop
// Parameters: None
// Returns: None
// Description: Generates the stop condition in the i2c line
//--------------------------------------------------------------------------------------
void
i2c_stop(void)
{
    unsigned int i;

  iicm_u0smr =1;
   //Delay
stpreq_u0smr4 = 1;   // Stop condition generate bit
   // Delay
    stspsel_u0smr4 = 1;  // SCL, SDA output select bit
Delay
    stspsel_u0smr4 = 0;  // SCL, SDA output select bit

while(stpreq_u0smr4==1)  ;

  }

//--------------------------------------------------------------------------------------
// Name:  i2c_enable_rx
// Parameters: None
// Returns: None
// Description: Enables the transmission of uart0
//--------------------------------------------------------------------------------------
void i2c_enable_rx(void)
{
te_u0c1 = 0;    // Transmit data (enable bit)
re_u0c1 = 0;    // enable rx

te_u0c1 = 1;    // Transmit data (enable bit)

    while(!ti_u0c1);   // wait for tx buffer to be empty
   while(!txept_u0c0); // wait for tx register to empty

re_u0c1 = 1;    // enable rx

}

//--------------------------------------------------------------------------------------
// Name:  i2c_init
// Parameters: None
// Returns: None
// Description: This routine configures UART0 as i2c
//--------------------------------------------------------------------------------------
void i2c_init(void)
{  unsigned char uart0_tmp = 0 ;
/*
    u0mr = 0x02;     // i2c mode, internal clock
u0c0 = 0xB0;     // clk = f1, MSB first

u0c1 = 0x00;                 // disable reception and transmission

u0brg =82;                //BRG=82;for 100kbps //it must be set after setting bits in uic0.
u0smr = 0x03;     // i2c mode, arbitration lost by byte
u0smr2 = 0x02;    // ack/nack int, with  clock sinchronization
u0smr3 = 0x20;   // no clock delayed, clock out cmos, with 1-2 cycles data delay   
u0smr4 = 0x00; 
*/
     u0c1 = 0x00;     // disable reception and transmission
 
    p6 = 0x00 ;                         // Port6 initialize
    pd6_2 = 0x01 ;                      //      P6_2 is an output port
    pd6_3 = 0x01 ;                      //      P6_3 is an output port
    p6_2s = 0x03 ;                      //      P6_2 is SCL0 output
    p6_3s = 0x03 ;                      //      P6_3 is SDA0 output

uart0_tmp = u0mr ;                  // (9) Serial interface disabled
    uart0_tmp &= 0xf8 ;                 //
    u0mr = uart0_tmp ;                  //

u0mr = 0x02;     // i2c mode, internal clock.

    u0c0 = 0xB0;     // clk = f1, MSB first
  
    u0brg = 0xFF;     // BRG = FFh minimum value.This register should be rewritten after setting bits CLK1 and CLK0 in the UiC0 register.


   
u0smr = 0x03;         // i2c mode, arbitration lost by byte
u0smr2 = 0x00;     // ack/nack int, with NO clock sinchronization
u0smr3 = 0x60;     // clock delayed, clock out cmos, with no data delay

p0=0x00;
  p1=0x00;
  pd0=0xff;pd1=0xff; pd10=0xff;
 
ifsr0 |= 0x40;

s0tic|=0x01;//interrupt priority is 1.
s0ric|=0x01;

  u0c1 = 0x05; //enable transmission & reception
}

twelvexs Newbie 20 posts since
Jul 28, 2008
Currently Being Moderated
Jun 22, 2009 8:50 AM in response to: Nrapl
Re: Problem with UART0 in I2C mode

Are you sending the correct address to the EEPROM on the I2C bus? You say that you're checking the I2C bus lines after the START condition, however are you seeing the slave address transmitted on the bus lines?

More Like This

  • Retrieving data ...

Bookmarked By (0)