|
|
View previous topic :: View next topic |
Author |
Message |
jguarin2002
Joined: 11 Nov 2007 Posts: 5
|
i2c_write(), problem |
Posted: Sun Nov 11, 2007 7:30 pm |
|
|
Ok here it is. Im trying to write data to this device (24lc128 a 16k serial eeprom) through a i2c bus... but it doesnt work. I used the 24c128.c and started to debug it. Finally I hacked this little code where I think the problem is roaming.
I try to write a single byte of data in the memory, using the memory's standard procedure and the i2c_functions CCS provides:
Code: |
i2c_start();//Runs fine oscilloscope tested. Both lines became drive by mcu and start condition happens.
i2c_write(0xa0);//Device id and write bit set fine (SDA & SCL oscilloscope tested).
i2c_write(0xHB);//HIGH BYTE ADDRESS fine (SDA & SCL oscilloscope tested)
i2c_write(0xLB);//LOW BYTE ADDRESS BYTE fine (SDA & SCL oscilloscope tested).
i2c_write(_8_bit_data);// HERE IS THE ERROR in the oscilloscope appears a 1's bit train = 0xff rather than _8_bit_data bits!.
i2c_stop(); //Also works fine!
|
Anybody out there detected this? I read about many people getting 0xff in their memory readings... perhaps the problem was in the i2c_write stage?. _________________ Julián Andrés Guarín |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 11, 2007 7:42 pm |
|
|
1. Post your compiler version.
2. Post the #define statement for hi(x) in the 24128.c file. |
|
|
jguarin2002
Joined: 11 Nov 2007 Posts: 5
|
|
Posted: Sun Nov 11, 2007 8:16 pm |
|
|
Ok version is 3.236
The #define statement is
#define hi(x) *(&x+1)
which i think is right.
anyway im not using this define or any other macro defined in the driver file (24128.c) cause im not using it longer for the example I posted.
The problem comes at the moment you attempt to write the data, just after you selected the device (SDA checked OK), the address high byte (SDA checked OK), the address low byte (SDA checked OK).
When the MCU executes:
i2c_write(the_data_to_write_in_memory);
You should see in the oscilloscope the SDA line showing the_data_to_write_in_memory bit train, but instead of that you see its a 0xff bit train. Thats wrong and its a MCU error, non a protocol one, etc. etc.
I think i could check the .LST file and "desk test" what is happenning but took too long cause im not used to asm hack (hate it), but I prefer to c-hack a little and set the data bit train the right way by myself, setting 1's and 0's in the code, rather than i2c_write(data). However I hope you can tell me if there's an error or something.
regards. _________________ Julián Andrés Guarín |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 11, 2007 10:00 pm |
|
|
Quote: | i2c_write(0xHB);
i2c_write(0xLB);
i2c_write(_8_bit_data);
|
Post a complete test program with real values for the parameters,
instead of the values shown above. Post all the #include, #use i2c(),
#use delay(), and #fuses statements. |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 12, 2007 3:09 am |
|
|
The 'hi' define, should work with your compiler, but is dangerous.
In C, if you add one to a variable address, it is meant to increment the physical address, by the size of the variable. The older releases of CCS (V3), instead incremented the address by just one. On the newer compilers this was changed to the 'proper' syntax, leading to quite a few problems...
Hence, I'd make the 'hi' definition 'future proof', by using:
#define hi(x) (*((int8*)&x+1))
Which casts the address so that it is seen as a pointer to an int8 type, whatever the actual 'type' of x is. The danger, is that if your compiler was a slightly latter version, and you were still using the 'older' define, the wrong data would be sent. Hence PCM programmer, is checking that the define you have should work for your compiler.
Now, there isno difference in chip terms, between any I2C_WRITE and another. If the first two bytes are being sent OK, then the problem is that the data being presented to the third one, is in some way, not what is expected.
Hence, do something simple like:
1) What is the chip.
2) Do a minimum test program, with the defintion lines included as PCM programmer askd.
3) Try:
Code: |
i2c_start();
i2c_write(0xa0);
i2c_write(0xHB);
i2c_write(0xLB);
i2c_write(_8_bit_data);
i2c_stop();
printf("%2x %2x %2x\n\r",0xHB,0xLB,_8_bit_data);
|
With the proper data defintions substituted.
What does print?...
Best Wishes |
|
|
Guest
|
|
Posted: Mon Nov 12, 2007 5:21 pm |
|
|
Hello Ttelmah
Thanks for your help.
I agree with you about the problems related to pointer arithmetics, the point here is that im not using this macro definition, as you mentioned because of "compiler" portability problems afterwards.
Now. Im using PCH 18F258 CCS routines.
I've already check the values with printf. They are correct.
Im using I2C to write a single byte of data to a random address in a 24LC128 16Kbytes serial memory. To do that im using the i2c_write,i2c_stop,i2c_start CCS routines. Also im checking the i2c lines SDA and SCL.
SCL works fine all the time and SDA almost all the time.
Im using the following code to write to the memory:
data=30; /* 0x1e */
i2c_start(); //Set the start condition. SDA and SCL lines checked. Everything here is fine.
i2c_write(0xa0); //Device selection, master to slave direction. SDA check and ok (i can see the 10100000 train bit in the oscilloscope probe), also the slave device (the memory) holds down the SDA line performing an ACK.
i2c_write(0x00);//High byte address (everything went ok on SDA : 000000000's bit train and the ACK stuff).
i2c_write(0x01);//Low byte address (yes im writing to the 0x0001 address and everything went ok on SDA : 00000001's bit train and the ACK stuff).
i2c_write(data);//Data to write...... everything goes down here!!! I do not see in the SDA the 0x1e=00001110 train bit, instead of that I catch an ugly 11111111=0xff byte.
i2c_stop(); /* Stop condition issued, lines go into input mode then the pull up resistor acts setting SDA and SCL high. This also works fine */
So whats happening? Well i dont know whats happening after the first 3 writes but it seems that in the fourth i2c_write the SSPBUF is not being loaded with my 0x1e value but with a 0xff.
The problem is that i2c_write() is missperforming because it is not setting the correct value in the bus the fourth time.!
Why such a thing can happen?
Any idea? [/b] |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 12, 2007 5:29 pm |
|
|
1. Disconnect the eeprom from the PIC.
2. Leave only the pull-up resistors connected to the SDA and SCL pins
on the PIC.
3. Run the test program again and see if it still has the problem.
If you still have the problem, then post a complete test program that
contains the lines of code that you posted. Also show the #include,
#fuses, #use delay() and #use i2c() statements. |
|
|
Guest
|
|
Posted: Mon Nov 12, 2007 9:27 pm |
|
|
Now it worked...!!!
The problem was that I was maybe outperforming the slave device or the protocol itself. I set a delay time between the write procedure code and the read procedure code... lo and behold! run just fine. Hope it keeps working.
Anyway I want to thanks to all the people that posted to help. specially PCM programmer and the other user.... thank you for your time. |
|
|
|
|
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
|