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
}