View previous topic :: View next topic |
Author |
Message |
johanpret
Joined: 23 Oct 2006 Posts: 33 Location: South Africa
|
|
Posted: Tue Jan 09, 2018 1:20 pm |
|
|
I have a different I2C chip and experience the same behaviour. 32000000 it work and 64000000 it does not. Chip APDS9960. Any ideas. _________________ Johan Pretorius |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 09, 2018 1:39 pm |
|
|
What is your PIC and compiler vs. ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Tue Jan 09, 2018 2:02 pm |
|
|
Try using my 1206 driver from the code library. I have this running on PIC24's at 30MIPS (60MHz) without problems.
On the existing driver, add delay_us(1) after every I2C_stop.
I've seen problems where there is a stop at the end of a function, and the next function is called immediately and starts again, at high clock speeds. The I2C returns before the 'stop' has been set long enough to be recognised by all chips.... |
|
|
johanpret
Joined: 23 Oct 2006 Posts: 33 Location: South Africa
|
|
Posted: Thu Jan 18, 2018 9:21 am |
|
|
I wrote my own I2C Software Library. Now I can talk to the chip when the clock speed is 64000000. Something in the build in Library causes a failure when i run at 64000000 clock speed. At 3200000 working with internal Library.
My own library work at 64000000.
Here is my Library:
Code: |
void jp_I2C_Init(void)
{
output_float(JP_I2C_SCL);
output_float(JP_I2C_SDA);
}
void JP_I2C_Start(void)
{
delay_us(2);
output_bit(JP_I2C_SDA,0);
delay_us(1);
output_bit(JP_I2C_SCL,0);
delay_us(1);
}
byte JP_I2C_Write(Byte WriteData)
{
byte i2,Acknowledge;
for (i2=0;i2<8;i2++)
{
output_bit(JP_I2C_SDA,bit_test(WriteData,7-i2));
delay_us(1);
output_float(JP_I2C_SCL);
delay_us(1);
output_bit(JP_I2C_SCL,0);
}
output_float(JP_I2C_SDA);
delay_us(1);
output_float(JP_I2C_SCL);
delay_us(1);
Acknowledge = input(JP_I2C_SDA);
output_bit(JP_I2C_SCL,0);
delay_us(1);
Return(Acknowledge);
}
byte JP_I2C_Read(byte Ack)
{
byte i2,Acknowledge,Data=0;
for (i2=0;i2<8;i2++)
{
output_float(JP_I2C_SCL);
delay_us(1);
if (input(JP_I2C_SDA) == 1) bit_set(Data,7-i2);
output_bit(JP_I2C_SCL,0);
delay_us(1);
}
if (Ack == 1) output_bit(JP_I2C_SDA,0);
delay_us(1);
output_float(JP_I2C_SCL);
delay_us(1);
output_bit(JP_I2C_SCL,0);
output_float(JP_I2C_SDA);
delay_us(1);
Return(Data);
}
void JP_I2C_Restart(void)
{
output_float(JP_I2C_SCL);
delay_us(1);
output_bit(JP_I2C_SDA,0);
delay_us(1); //4
output_bit(JP_I2C_SCL,0);
delay_us(1); //4
}
void JP_I2C_Stop(void)
{
output_bit(JP_I2C_SDA,0);
delay_us(1); //4
output_float(JP_I2C_SCL);
delay_us(1);
output_float(JP_I2C_SDA);
delay_us(1); //4
}
void Write_Register_APDS_9960(byte RegisterAddress, byte Value)
{
jp_i2c_start();
jp_i2c_write((APDS9960_I2C_ADDR<<1) | 0);
jp_i2c_write(RegisterAddress);
jp_i2c_write(Value);
jp_i2c_stop();
}
byte Read_Register_APDS_9960(byte RegisterAddress)
{
byte jp_data;
jp_i2c_start();
jp_i2c_write((APDS9960_I2C_ADDR<<1) | 0);
jp_i2c_write(RegisterAddress); // Data to device
jp_i2c_restart(); // Restart
jp_i2c_write((APDS9960_I2C_ADDR<<1) | 1);
jp_data=jp_i2c_read(0);
jp_i2c_stop();
Return(jp_data);
} |
_________________ Johan Pretorius |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Thu Jan 18, 2018 9:41 am |
|
|
All i get from google is that 'apds9960' is some rgb /motion sensor NOT an OLED display.
Can you show link to your OLED display ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Thu Jan 18, 2018 9:46 am |
|
|
The thing that is essential, is the little change I gave earlier:
Quote: |
On the existing driver, add delay_us(1) after every I2C_stop.
|
The chip requires a minimum of 1.3uSec between a stop and a subsequent start. There are several instructions always between the two, and up to about 40MHz, these are enough, but I found at 64Mhz, the time could be as little as 0.9uSec, which causes problems. |
|
|
johanpret
Joined: 23 Oct 2006 Posts: 33 Location: South Africa
|
|
Posted: Thu Jan 18, 2018 11:28 pm |
|
|
This is the second I2c chip that had the same problem as the i2c
oled. I will test on i2c oled as well. I did put a delay after each i2c_stop() on the built-in driver with no success @ 60000000 so i really don't know why it fail. _________________ Johan Pretorius |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Fri Jan 19, 2018 6:37 am |
|
|
If this 2nd device is the Avago RGB/gesture chip you need to add 1.3us MINIMUM between I2C Bus Stop and Start. I'd delay_us(2) to be sure. In the AC electrial characteristics chart, item 2 is kinda important. Actually all of it is.
Also
at 64MHz... period is a bit over 15ns. The rise and fall times for the device is minumum 20ns, so you may be violating that spec as well..
Then there's the whole PCB layout,wiring,pin loading, power supply, etc. A good scope will show you the waveforms.
While you PIC may like running at 60+MHz, you need to be sure to conform to the peripheral device specs pay attention to temperature range as well. Often timings will vary,some times a LOT, depending on how hot or cold it is.
Jay |
|
|
johanpret
Joined: 23 Oct 2006 Posts: 33 Location: South Africa
|
|
Posted: Fri Jan 19, 2018 7:49 am |
|
|
There is a 1 us at the end of stop and a 2us before start process is initiated. I agree with all that you are saying I was just sharing my experience with internal i2c functions not working 64000000 clock speed. But it worked with 32000000. As far as i know the i2c speed should follow speed specification selected in the setup of the i2c. But for some reason not known to me the internal driver failed @ 64000000. When using my own software bit banging i2c driver, it worked @ 64000000. Most of the things you mentioned we did take into account with the hardware. So i just share the driver. It might help someone who is struggling. When i have some free time I will compare and try and identify the problem on internal software i2c driver from ccs. _________________ Johan Pretorius |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Fri Jan 19, 2018 8:14 am |
|
|
It's not just the 1us delay between stop and start, you need to consider the rise and fall 'transition' times. When you double the clock speed you half those transition times. It's quite possible the I2C device never 'sees' the transition as it's too fast to process.
This is not the fault of the driver (software) but a known limitation of the device (hardware).
Years ago lots of people got into 'trouble' by overclocking their PCs. While the CPU could operate, RAM couldn't and so the computer would 'lockup'.
This is a similar situation.
Jay |
|
|
johanpret
Joined: 23 Oct 2006 Posts: 33 Location: South Africa
|
|
Posted: Fri Jan 19, 2018 10:36 am |
|
|
The rise and fall time stay the same for a specific hardware configuration so if you increase the speed there might not be enough time to fall or rise between changes. This will be the bandwidth limitation of the hardware and if your hardware can't handle more than a certain frequency that is your limit. Any way if you implement the the I2C specification 100kHz or 400kHz or 1Mhz then even if you change the clock speed of the microcontroller your driver must adapt for this higher clock speed and keep to the specification if the configured I2C []. That is what I would suspect.
#USE I2C (options)
FAST
Use the fast I2C specification.
FAST=nnnnnn
Sets the speed to nnnnnn hz
SLOW
Use the slow I2C specification
Software implementation might be more difficult as to your need to take into account compiler directives for instance use standard_io or fast io which produce more or less instructions. As long as you make sure you are at least slower than the specification you are trying to adhere to you should be ok. Accept if the device you are trying to control are time sensitive as well then you must really be careful with timing. The WS2812B LED for instance You can't control if you cant communicate fast enough. With something like this you even need to switch off interrupts while communicating or communication will fail.
SO That is why I suspect the software implementation of the I2C driver from CCS has some issue with the timing when using 64000000. The reason being if you look at my implementation it is implemented to be slightly slower than the 400kHz I2C specification. With this implementation I am able to communicate with the Oled display and the APDS9960 chip @ 64000000. _________________ Johan Pretorius |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Fri Jan 19, 2018 1:45 pm |
|
|
It's be intersting to see what the listings look like 32MHz vs 64 MHz. Should be easy to spot all the differences. |
|
|
|