CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problem - i2c_read() always returning 0?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jeferson_ev



Joined: 07 Jan 2009
Posts: 3

View user's profile Send private message MSN Messenger

Problem - i2c_read() always returning 0?
PostPosted: Thu Jan 08, 2009 10:14 pm     Reply with quote

Hi.
I'm starting to use I2C interface to communicate with external periphals. My first test was with an EEPROM (M24256 from ST Microelectronics).
I'm trying to make a "byte write" and a "random address read". Writing is OK, but when I try to read a memory address the value returned by "i2c_read()" instruction is always 0.
I used hyperterminal to show the readed values (image below)
->I'm using CCS v4.084.

Code:

//----------------------------------------------------------------------------
//--------------------------------I2C BUS-------------------------------------
//----------------------------------------------------------------------------

#INCLUDE <30F4011.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT_PLL16                 //XT Crystal Oscillator mode with 16X PLL
#FUSES PR                       //Primary Oscillator
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES PUT64                    //Power On Reset Timer value 64ms
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#USE DELAY(Clock=64M)           //4Mhz Crystal with 16X PLL (Is that right?)
#USE RS232(UART2,Baud=57600,Parity=N,Bits=8)
#USE I2C(Master,Slow,SDA=PIN_F2,SCL=PIN_F3,FORCE_HW)
//----------------------------------------------------------------------------
//--------------------DEFINES,VARIABLES AND FUNCIOTNS-------------------------
//----------------------------------------------------------------------------
#DEFINE LED PIN_D3
#DEFINE EEPROM_WRITE_CMD 0xA0  //= 1010|000|0 in binary
#DEFINE EEPROM_READ_CMD 0xA1   //= 1010|000|1 in binary

void led_flash();

int1 i2c_ack;
long value;
//----------------------------------------------------------------------------
//-------------------------------FIRMWARE-------------------------------------
//----------------------------------------------------------------------------
void main()
{
   SET_TRIS_B(0b0000000000000000); 
   SET_TRIS_C(0b0000000000000000);
   SET_TRIS_D(0b0000000000000000);
   SET_TRIS_E(0b0000000000000000);
   SET_TRIS_F(0b0000000000010000);
   SETUP_ADC(ADC_OFF);
   SETUP_WDT(WDT_OFF);
   DISABLE_INTERRUPTS(INT_RDA2);
   DISABLE_INTERRUPTS(INT_TBE2);
   DISABLE_INTERRUPTS(INT_TIMER1);
   DISABLE_INTERRUPTS(INT_TIMER2);
   DISABLE_INTERRUPTS(INT_TIMER3);
   DISABLE_INTERRUPTS(INT_TIMER4);
   DISABLE_INTERRUPTS(INT_TIMER5);
   DISABLE_INTERRUPTS(INTR_GLOBAL); 
   DISABLE_INTERRUPTS(INTR_NORMAL);
   
   delay_ms(300);
   
//----------------------------------------------------------------------------
//----------------------Writes 123d on memory adress 5------------------------
//----------------------------------------------------------------------------
   printf("EEPROM Write");
   i2c_start(); //I2C Start
   
   i2c_ack=i2c_write(EEPROM_WRITE_CMD);  //Write CMD = 1010|000|0 in binary
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(EPROM_WRITE_CMD)"); break;}
            case 1: {printf("\r\nNO_ACK i2c_write(EPROM_WRITE_CMD)"); break;}
         }
         
   i2c_ack=i2c_write(0x00);  //Memory Adress High
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(0x00)"); break;}
            case 1: {printf("\r\nNO_ACK on i2c_write(0x00)"); break;}
         }
         
   i2c_ack=i2c_write(0x05); //Memory Adress Low
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(0x05)"); break;}
            case 1: {printf("\r\nNO_ACK on i2c_write(0x05)"); break;}
         }
         
   i2c_ack=i2c_write(123); //Writes 123d on memory adress 5
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(123)"); break;}
            case 1: {printf("\r\nNO_ACK i2c_write(123)"); break;}
         }
         
   i2c_stop();  //I2C Stop
   
   
   delay_ms(300);
//----------------------------------------------------------------------------
//------------------Reads the content of memory adress 5----------------------
//----------------------------------------------------------------------------

printf("\r\nEEPROM Read");
   i2c_start(); //I2C Start
   
   i2c_ack=i2c_write(EEPROM_WRITE_CMD); //Write CMD = 1010|000|0 in binary 
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(EEPROM_WRITE_CMD)"); break;}
            case 1: {printf("\r\nNO_ACK on i2c_write(EEPROM_WRITE_CMD)"); break;}
         }
         
   i2c_ack=i2c_write(0x00); //Memory Adress High
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(0x00)"); break;}
            case 1: {printf("\r\nNO_ACK on i2c_write(0x00)"); break;}
         }
         
   i2c_ack=i2c_write(0x05); //Memory Adress Low
         switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(0x05)"); break;}
            case 1: {printf("\r\nNO_ACK on i2c_write(0x05)"); break;}
         }
         
   i2c_start(); // Second I2C Start
   
   i2c_ack=i2c_write(EEPROM_READ_CMD); //Read CMD = 1010|000|1 in binary 
          switch(i2c_ack)
         {
            case 0: {printf("\r\nACK on i2c_write(EEPROM_READ_CMD)"); break;}
            case 1: {printf("\r\nNO_ACK on i2c_write(EEPROM_READ_CMD)"); break;}
         }
   
   while(I2C_POLL()==FALSE) //waits for I2C data reception
   {
   
   }
   
   value=i2c_read(); //value = adress 5 content
   
   i2c_stop();  //I2C Stop

   printf("\r\n");
   printf("VALUE = %lu", value); //prints the content of value
 
   while(TRUE)
   {
   led_flash();
   }
   
}

void led_flash()
   {
   output_toggle(LED);
   delay_ms(200); 
   }


-------------------------------------------------------------------------
Code showed on Hyperterminal:
http://img151.imageshack.us/my.php?image=eepromuc1.png

The EEPROM acknowledges the writed bytes but value=0 always.
Putting A0 (EEPROM physical address input) to VCC, the EEPROM returns NOACK, this means that the EEPROM is being addressed correctly, but i2c_read() is always returning 0 to the variable value.
-------------------------------------------------------------------------

M24256 EEPROM datasheet shows:
http://img368.imageshack.us/my.php?image=m24256lk5.png
My code does this sequence but I don't know why it isn't working correctly

-------------------------------------------------------------------------
Circuit used:
http://www.speedyshare.com/616555732.html
Pullups resistors on SCL and SDA = 2.2K
PIC used = dsPIC30F4011

M24256 EEPROM Datasheet:
http://www.st.com/stonline/products/literature/ds/6757/m24256-bw.pdf

Somebody knows whats wrong?
Help Plz Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 08, 2009 11:08 pm     Reply with quote

Your code is overly complicated, which is preventing you from seeing
certain things. Look at the read_ext_eeprom() function in the CCS
driver. What parameter is used in the last i2c_read() operation ?
Quote:
c:\program files\picc\drivers\24256.c


Look at page 19 in the M24256 data sheet, at this figure:
Quote:
Figure 11. Read mode sequences

What operation is done on the last i2c read, when it gets "data out" ?

Look in the CCS manual at the i2c_read() function to see what the
parameter is used for in that function.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Jan 08, 2009 11:46 pm     Reply with quote

It looks to me like the problem is with the polling loop while reading data from EEPROM.
Try to test the code without:
Code:

while(I2C_POLL()==FALSE) //waits for I2C data reception
   {
   
   }

_________________
Every solution has a problem.
jeferson_ev



Joined: 07 Jan 2009
Posts: 3

View user's profile Send private message MSN Messenger

PostPosted: Fri Jan 09, 2009 2:14 pm     Reply with quote

n-squared wrote:
It looks to me like the problem is with the polling loop while reading data from EEPROM.
Try to test the code without:
Code:

while(I2C_POLL()==FALSE) //waits for I2C data reception
   {
   
   }

same result :(


hey PCM Programmer:
I've tryed with i2c_read(0) (without data in read ack, the datasheet M24256 shows this), but the value = 0 persists :(
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jan 10, 2009 7:30 pm     Reply with quote

1. Your schematic doesn't have capacitors on the crystal.
Look at the schematic on page 106 of the dsPICDEM 2 Development
Board User’s Guide:
http://ww1.microchip.com/downloads/en/DeviceDoc/dsPICDEM%202%20Users%20Guide%20DS-51558A.pdf
It shows 22 pf capacitors on either side of the external crystal.

2. Your posted code is too complicated. I would start by using software
i2c instead of hardware i2c. It's possible that CCS doesn't have the
hardware i2c code working. Also, I would get rid of all the printf and ack
stuff and simply try to make it work.

3. The hardware i2c pins on this PIC are also the pins used by the ICD
debugger (PGC and PGD). If you have an ICD debugger connected to
those pins, it may not work. I'd suggest using software i2c on different
pins than F2 and F3.

Here's an example of stripped down code. It doesn't attempt to do ack-
polling. It just does a delay after the write operation. It uses software
i2c.
Code:
#use i2c(Master, SDA=PIN_F2, SCL=PIN_F3 )

#DEFINE LED PIN_D3

void led_flash();

//==================================
void main()
{
   int8 value;

   printf("Write\n\r");

   i2c_start();
   i2c_write(0xA0); 
   i2c_write(0x00); 
   i2c_write(0x00); 
   i2c_write(0x55); 
   i2c_stop();   

   delay_ms(5);  // Do this for now (instead of ack-polling).
   
   printf("Read\n\r");

   i2c_start(); 
   i2c_write(0xA0); 
   i2c_write(0x00); 
   i2c_write(0x00); 
   i2c_start();      // Re-start
   i2c_write(0xA1);   
   value = i2c_read(0); 
   i2c_stop(); 

   printf("Value = %X \n\r", value);
 
   while(TRUE)
   {
   led_flash();
   }
   
}

//====================
void led_flash()
   {
   output_toggle(LED);
   delay_ms(200); 
   }
 
jeferson_ev



Joined: 07 Jan 2009
Posts: 3

View user's profile Send private message MSN Messenger

OK
PostPosted: Mon Jan 12, 2009 4:55 pm     Reply with quote

PCM Programmer:
Your code works fine.
I've tried the code in a PIC18F4455 and it worked.
I've also tried on my dsPIC30F4011 and it doesnt work. (I've used my dspic30f4011 on many school projects and I think some I/O pins are damaged, like the pins used by I2C SCL and SDA, maybe)

Big thanks for you PCM programmer and who helped.
Cool
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group